[systemd-commits] 7 commits - configure.ac .gitignore Makefile.am Makefile-man.am man/systemd-analyze.xml man/systemd-verify.xml shell-completion/bash shell-completion/zsh src/analyze src/shared src/sysusers src/update-done src/verify TODO
Zbigniew JÄdrzejewski-Szmek
zbyszek at kemper.freedesktop.org
Mon Jul 21 19:49:48 PDT 2014
.gitignore | 1
Makefile-man.am | 2
Makefile.am | 31 +-
TODO | 3
configure.ac | 2
man/systemd-analyze.xml | 122 ++++++++++-
man/systemd-verify.xml | 174 ----------------
shell-completion/bash/systemctl.in | 2
shell-completion/bash/systemd-analyze | 9
shell-completion/zsh/_sd_unit_files | 9
shell-completion/zsh/_systemctl.in | 6
shell-completion/zsh/_systemd-analyze | 12 +
src/analyze/analyze-verify.c | 280 ++++++++++++++++++++++++++
src/analyze/analyze-verify.h | 26 ++
src/analyze/analyze.c | 94 +++++---
src/shared/fileio-label.c | 2
src/shared/missing.h | 12 +
src/shared/path-lookup.c | 2
src/sysusers/sysusers.c | 45 ++--
src/update-done/update-done.c | 25 +-
src/verify/Makefile | 1
src/verify/verify.c | 363 ----------------------------------
22 files changed, 582 insertions(+), 641 deletions(-)
New commits:
commit 142c4ecaa9840714d49b40b1de407748b52f21d7
Author: Zbigniew JÄdrzejewski-Szmek <zbyszek at in.waw.pl>
Date: Mon Jul 21 21:14:08 2014 -0400
man: merge systemd-verify with systemd-analyze
diff --git a/Makefile-man.am b/Makefile-man.am
index 5cc3081..4339e50 100644
--- a/Makefile-man.am
+++ b/Makefile-man.am
@@ -92,7 +92,6 @@ MANPAGES += \
man/systemd-udevd.service.8 \
man/systemd-update-done.service.8 \
man/systemd-update-utmp.service.8 \
- man/systemd-verify.1 \
man/systemd.1 \
man/systemd.automount.5 \
man/systemd.device.5 \
@@ -1659,7 +1658,6 @@ EXTRA_DIST += \
man/systemd-update-utmp.service.xml \
man/systemd-user-sessions.service.xml \
man/systemd-vconsole-setup.service.xml \
- man/systemd-verify.xml \
man/systemd.automount.xml \
man/systemd.device.xml \
man/systemd.directives.xml \
diff --git a/man/systemd-analyze.xml b/man/systemd-analyze.xml
index c7a2598..073e807 100644
--- a/man/systemd-analyze.xml
+++ b/man/systemd-analyze.xml
@@ -95,6 +95,12 @@
<arg choice="plain">set-log-level</arg>
<arg choice="opt"><replaceable>LEVEL</replaceable></arg>
</cmdsynopsis>
+ <cmdsynopsis>
+ <command>systemd-analyze</command>
+ <arg choice="opt" rep="repeat">OPTIONS</arg>
+ <arg choice="plain">verify</arg>
+ <arg choice="opt" rep="repeat"><replaceable>FILES</replaceable></arg>
+ </cmdsynopsis>
</refsynopsisdiv>
<refsect1>
@@ -103,7 +109,8 @@
<para><command>systemd-analyze</command> may be used
to determine system boot-up performance statistics and
retrieve other state and tracing information from the
- system and service manager.</para>
+ system and service manager, and to verify the
+ correctness of unit files.</para>
<para><command>systemd-analyze time</command>
prints the time spent in the kernel before
@@ -171,6 +178,17 @@
described in
<citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>).</para>
+ <para><command>systemd-analyze verify</command> will
+ load unit files and print warnings if any errors are
+ detected. Files specified on the command line will be
+ loaded, but also any other units referenced by
+ them. This command works by prepending the directories
+ for all command line arguments at the beginning of the
+ unit load path, which means that all units files found
+ in those directories will be used in preference to the
+ unit files found in the standard locations, even if
+ not listed explicitly.</para>
+
<para>If no command is passed, <command>systemd-analyze
time</command> is implied.</para>
@@ -185,17 +203,16 @@
<varlistentry>
<term><option>--user</option></term>
- <listitem><para>Shows performance data
- of user sessions instead of the system
- manager.</para></listitem>
+ <listitem><para>Operates on the user
+ systemd instance.</para></listitem>
</varlistentry>
<varlistentry>
<term><option>--system</option></term>
- <listitem><para>Shows performance data
- of the system manager. This is the
- implied default.</para></listitem>
+ <listitem><para>Operates on the system
+ systemd instance. This is the implied
+ default.</para></listitem>
</varlistentry>
<varlistentry>
@@ -257,6 +274,14 @@
e.g. "50ms".</para></listitem>
</varlistentry>
+ <varlistentry>
+ <term><option>--no-man</option></term>
+
+ <listitem><para>Do not invoke man to verify the existence
+ of man pages listen in <varname>Documentation=</varname>.
+ </para></listitem>
+ </varlistentry>
+
<xi:include href="user-system-options.xml" xpointer="host" />
<xi:include href="user-system-options.xml" xpointer="machine" />
@@ -275,20 +300,87 @@
</refsect1>
<refsect1>
- <title>Examples</title>
+ <title>Examples for <command>dot</command></title>
- <para>This plots all dependencies of any unit whose
- name starts with <literal>avahi-daemon.</literal>:</para>
+ <example>
+ <title>Plots all dependencies of any unit whose
+ name starts with <literal>avahi-daemon</literal></title>
- <programlisting>$ systemd-analyze dot 'avahi-daemon.*' | dot -Tsvg > avahi.svg
-$ eog avahi.svg</programlisting>
+ <programlisting>$ systemd-analyze dot 'avahi-daemon.*' | dot -Tsvg > avahi.svg
+ $ eog avahi.svg</programlisting>
+ </example>
- <para>This plots the dependencies between all known target units:</para>
+ <example>
+ <title>Plots the dependencies between all known target units</title>
- <programlisting>systemd-analyze dot --to-pattern='*.target' --from-pattern='*.target' | dot -Tsvg > targets.svg
+ <programlisting>systemd-analyze dot --to-pattern='*.target' --from-pattern='*.target' | dot -Tsvg > targets.svg
$ eog targets.svg</programlisting>
+ </example>
+ </refsect1>
-
+ <refsect1>
+ <title>Examples for <command>verify</command></title>
+
+ <para>The following errors are currently detected:</para>
+ <itemizedlist>
+ <listitem><para>unknown sections and
+ directives, </para></listitem>
+
+ <listitem><para>missing dependencies which are
+ required to start the given unit,
+ </para></listitem>
+
+ <listitem><para>man pages listed in
+ <varname>Documentation=</varname> which are
+ not found in the system,</para></listitem>
+
+ <listitem><para>commands listed in
+ <varname>ExecStart=</varname> and similar
+ which are not found in the system or not
+ executable.</para></listitem>
+ </itemizedlist>
+
+ <example>
+ <title>Misspelt directives</title>
+
+ <programlisting>$ cat ./user.slice
+[Unit]
+WhatIsThis=11
+Documentation=man:nosuchfile(1)
+Requires=different.service
+
+[Service]
+Desription=x
+
+$ systemd-verify ./user.slice
+[./user.slice:9] Unknown lvalue 'WhatIsThis' in section 'Unit'
+[./user.slice:13] Unknown section 'Service'. Ignoring.
+Error: org.freedesktop.systemd1.LoadFailed:
+ Unit different.service failed to load:
+ No such file or directory.
+Failed to create user.slice/start: Invalid argument
+user.slice: man nosuchfile(1) command failed with code 16
+ </programlisting>
+ </example>
+
+ <example>
+ <title>Missing service units</title>
+
+ <programlisting>$ tail ./a.socket ./b.socket
+==> ./a.socket <==
+[Socket]
+ListenStream=100
+
+==> ./b.socket <==
+[Socket]
+ListenStream=100
+Accept=yes
+
+$ systemd-verify ./a.socket ./b.socket
+Service a.service not loaded, a.socket cannot be started.
+Service b at 0.service not loaded, b.socket cannot be started.
+ </programlisting>
+ </example>
</refsect1>
<xi:include href="less-variables.xml" />
diff --git a/man/systemd-verify.xml b/man/systemd-verify.xml
deleted file mode 100644
index 128032e..0000000
--- a/man/systemd-verify.xml
+++ /dev/null
@@ -1,174 +0,0 @@
-<?xml version='1.0'?> <!--*-nxml-*-->
-<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
-"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
-
-<!--
-This file is part of systemd.
-
-Copyright 2014 Zbigniew JÄdrzejewski-Szmek
-
-systemd is free software; you can redistribute it and/or modify it
-under the terms of the GNU Lesser General Public License as published by
-the Free Software Foundation; either version 2.1 of the License, or
-(at your option) any later version.
-
-systemd is distributed in the hope that it will be useful, but
-WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-Lesser General Public License for more details.
-
-You should have received a copy of the GNU Lesser General Public License
-along with systemd; If not, see <http://www.gnu.org/licenses/>.
--->
-
-<refentry id="systemd-verify"
- xmlns:xi="http://www.w3.org/2001/XInclude">
-
- <refentryinfo>
- <title>systemd-verify</title>
- <productname>systemd</productname>
-
- <authorgroup>
- <author>
- <contrib>Developer</contrib>
- <firstname>Zbigniew</firstname>
- <surname>JÄdrzejewski-Szmek</surname>
- <email>zbyszek at in.waw.pl</email>
- </author>
- </authorgroup>
- </refentryinfo>
-
- <refmeta>
- <refentrytitle>systemd-verify</refentrytitle>
- <manvolnum>1</manvolnum>
- </refmeta>
-
- <refnamediv>
- <refname>systemd-verify</refname>
- <refpurpose>Check unit file validity</refpurpose>
- </refnamediv>
-
- <refsynopsisdiv>
- <cmdsynopsis>
- <command>systemd-verify</command>
- <arg choice="opt" rep="repeat">OPTIONS</arg>
- <arg choice="opt" rep="repeat">FILES</arg>
- </cmdsynopsis>
- </refsynopsisdiv>
-
- <refsect1>
- <title>Description</title>
-
- <para><filename>systemd-verify</filename> will load unit files and
- potentially print warnings if any errors are detected. Files
- specified on the command line will be loaded, but also any other
- units referenced by them.</para>
-
- <para>This command works by prepending the directories for all
- command line arguments at the beginning of the unit load path.
- This means that all units files found in those directories will
- be used in preference to the unit files found in the standard
- locations, even if not listed explicitly.</para>
-
- <para>The following errors are currently detected:</para>
- <itemizedlist>
- <listitem><para>unknown sections and directives,
- </para></listitem>
-
- <listitem><para>missing dependencies which are required to start
- the given unit,</para></listitem>
-
- <listitem><para>man pages listed in
- <varname>Documentation=</varname> which are not found in the
- system,</para></listitem>
-
- <listitem><para>commands listed in <varname>ExecStart=</varname>
- and similar which are not found in the system or not executable.
- </para></listitem>
- </itemizedlist>
- </refsect1>
-
- <refsect1>
- <title>Options</title>
-
- <para>The following options are understood:</para>
-
- <variablelist>
- <varlistentry>
- <term><option>--no-man</option></term>
-
- <listitem><para>Do not invoke man to verify the existence
- of man pages listen in <varname>Documentation=</varname>.
- </para></listitem>
- </varlistentry>
-
- <xi:include href="user-system-options.xml" xpointer="user" />
- <xi:include href="user-system-options.xml" xpointer="system" />
-
- <xi:include href="standard-options.xml" xpointer="help" />
- <xi:include href="standard-options.xml" xpointer="version" />
- </variablelist>
- </refsect1>
-
- <refsect1>
- <title>Exit status</title>
-
- <para>On success, 0 is returned, a non-zero failure
- code otherwise.</para>
- </refsect1>
-
- <refsect1>
- <title>Examples</title>
-
- <example>
- <title>Misspelt directives</title>
-
- <programlisting>$ cat ./user.slice
-[Unit]
-WhatIsThis=11
-Documentation=man:systemd.nosuchfile(7)
-Requires=different.service
-
-[Service]
-Desription=x
-
-$ systemd-verify ./user.slice
-[./user.slice:9] Unknown lvalue 'WhatIsThis' in section 'Unit'
-[./user.slice:13] Unknown section 'Service'. Ignoring.
-Error: org.freedesktop.systemd1.LoadFailed: Unit different.service failed to load: No such file or directory.
-Failed to create user.slice/start: Invalid argument
-user.slice: man systemd.nosuchfile(7) command failed with code 16
-</programlisting>
- </example>
-
- <example>
- <title>Missing service units</title>
-
- <programlisting>$ tail ./a.socket ./b.socket
-==> ./a.socket <==
-[Socket]
-ListenStream=100
-
-==> ./b.socket <==
-[Socket]
-ListenStream=100
-Accept=yes
-
-$ systemd-verify ./a.socket ./b.socket
-Service a.service not loaded, a.socket cannot be started.
-Service b at 0.service not loaded, b.socket cannot be started.
-</programlisting>
- </example>
-
- </refsect1>
-
- <refsect1>
- <title>See Also</title>
- <para>
- <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
- <citerefentry><refentrytitle>systemctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
- <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
- <citerefentry><refentrytitle>systemd.directives</refentrytitle><manvolnum>7</manvolnum></citerefentry>
- </para>
- </refsect1>
-</refentry>
commit 2c12a402cb1e8277c271ced8dc9c06d20b8f6017
Author: Zbigniew JÄdrzejewski-Szmek <zbyszek at in.waw.pl>
Date: Mon Jul 21 21:11:56 2014 -0400
shell-completion: systemd-analyze verify, systemctl link
Some zsh completion helpers were not installed, so completion
was broken.
Add systemd-analyze verify. Make systemctl link complete only
unit names.
diff --git a/Makefile.am b/Makefile.am
index 1cb77b9..55ed54d 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -407,6 +407,8 @@ dist_zshcompletion_DATA = \
shell-completion/zsh/_systemd-analyze \
shell-completion/zsh/_systemd-run \
shell-completion/zsh/_sd_hosts_or_user_at_host \
+ shell-completion/zsh/_sd_outputmodes \
+ shell-completion/zsh/_sd_unit_files \
shell-completion/zsh/_systemd-delta \
shell-completion/zsh/_systemd
diff --git a/TODO b/TODO
index 4a1313d..d964b52 100644
--- a/TODO
+++ b/TODO
@@ -704,6 +704,9 @@ External:
* register catalog database signature as file magic
+* zsh shell completion: <command> <verb> -<TAB> should complete options, but currently
+ does not
+
Regularly:
* look for close() vs. close_nointr() vs. close_nointr_nofail()
diff --git a/shell-completion/bash/systemctl.in b/shell-completion/bash/systemctl.in
index 4beec4e..c5950cc 100644
--- a/shell-completion/bash/systemctl.in
+++ b/shell-completion/bash/systemctl.in
@@ -89,7 +89,7 @@ _systemctl () {
comps=$(compgen -A signal)
;;
--type|-t)
- comps='automount device mount path service snapshot socket swap target timer'
+ comps='automount busname device mount path service snapshot socket swap target timer'
;;
--state)
comps='loaded not-found stub
diff --git a/shell-completion/bash/systemd-analyze b/shell-completion/bash/systemd-analyze
index 5575beb..77d1b54 100644
--- a/shell-completion/bash/systemd-analyze
+++ b/shell-completion/bash/systemd-analyze
@@ -44,6 +44,7 @@ _systemd_analyze() {
[CRITICAL_CHAIN]='critical-chain'
[DOT]='dot'
[LOG_LEVEL]='set-log-level'
+ [VERIFY]='verify'
)
_init_completion || return
@@ -99,6 +100,14 @@ _systemd_analyze() {
comps='debug info notice warning err crit alert emerg'
fi
+ elif __contains_word "$verb" ${VERBS[VERIFY]}; then
+ if [[ $cur = -* ]]; then
+ comps='--help --version --system --user --no-man'
+ else
+ comps=$( compgen -A file -- "$cur" )
+ compopt -o filenames
+ fi
+
fi
COMPREPLY=( $(compgen -W '$comps' -- "$cur") )
diff --git a/shell-completion/zsh/_sd_unit_files b/shell-completion/zsh/_sd_unit_files
new file mode 100644
index 0000000..4778a04
--- /dev/null
+++ b/shell-completion/zsh/_sd_unit_files
@@ -0,0 +1,9 @@
+#autoload
+
+_sd_unit_files() {
+ local files expl
+ files=( '*:files:->files' )
+
+ _description files expl 'unit file'
+ _files "$expl[@]" -g '*.(automount|busname|device|mount|path|service|snapshot|socket|swap|target|timer)'
+}
diff --git a/shell-completion/zsh/_systemctl.in b/shell-completion/zsh/_systemctl.in
index d9b8d1c..d364d17 100644
--- a/shell-completion/zsh/_systemctl.in
+++ b/shell-completion/zsh/_systemctl.in
@@ -261,7 +261,9 @@ for fun in set-environment unset-environment ; do
}
done
-(( $+functions[_systemctl_link] )) || _systemctl_link() { _files }
+(( $+functions[_systemctl_link] )) || _systemctl_link() {
+ _sd_unit_files
+}
# no systemctl completion for:
# [STANDALONE]='daemon-reexec daemon-reload default
@@ -297,7 +299,7 @@ _unit_states() {
_unit_types() {
local -a _types
- _types=(automount device mount path service snapshot socket swap target timer)
+ _types=(automount busname device mount path service snapshot socket swap target timer)
_values -s , "${_types[@]}"
}
diff --git a/shell-completion/zsh/_systemd-analyze b/shell-completion/zsh/_systemd-analyze
index 2eda5fe..c101ad0 100644
--- a/shell-completion/zsh/_systemd-analyze
+++ b/shell-completion/zsh/_systemd-analyze
@@ -6,6 +6,10 @@ _systemd_analyze_set-log-level() {
_describe -t level 'logging level' _levels || compadd "$@"
}
+_systemd_analyze_verify() {
+ _sd_unit_files
+}
+
_systemd_analyze_command(){
local -a _systemd_analyze_cmds
# Descriptions taken from systemd-analyze --help.
@@ -17,6 +21,7 @@ _systemd_analyze_command(){
'dot:Dump dependency graph (in dot(1) format)'
'dump:Dump server status'
'set-log-level:Set systemd log threshold'
+ 'verify:Check unit files for correctness'
)
if (( CURRENT == 1 )); then
@@ -38,7 +43,12 @@ _systemd_analyze_command(){
_arguments \
{-h,--help}'[Show help text.]' \
- '--user[Shows performance data of user sessions instead of the system manager.]' \
+ '--system[Operate on system systemd instance.]' \
+ '--user[Operate on user systemd instance.]' \
+ '--no-pager[Do not user pager.]' \
+ '--no-man[Do not check man pages.]' \
'--order[When generating graph for dot, show only order]' \
'--require[When generating graph for dot, show only requirement]' \
+ {-H+,--host=}'[Operate on remote host]:userathost:_sd_hosts_or_user_at_host' \
+ {-M+,--machine=}'[Operate on local container]:machine' \
'*::systemd-analyze commands:_systemd_analyze_command'
commit 1d3bc0177a1952473bbe45b5bbb4e4e4f69a84f4
Author: Zbigniew JÄdrzejewski-Szmek <zbyszek at in.waw.pl>
Date: Mon Jul 21 21:11:54 2014 -0400
Merge systemd-verify with systemd-analyze
diff --git a/.gitignore b/.gitignore
index 81bcc16..41fff4f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -122,7 +122,6 @@
/systemd-update-utmp
/systemd-user-sessions
/systemd-vconsole-setup
-/systemd-verify
/tags
/test-architecture
/test-async
diff --git a/Makefile.am b/Makefile.am
index 1cb7712..1cb77b9 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -350,8 +350,7 @@ bin_PROGRAMS = \
systemd-delta \
systemd-analyze \
systemd-run \
- systemd-path \
- systemd-verify
+ systemd-path
dist_bin_SCRIPTS = \
src/kernel-install/kernel-install
@@ -1226,19 +1225,6 @@ CLEANFILES += \
# ------------------------------------------------------------------------------
-systemd_verify_SOURCES = \
- src/verify/verify.c
-
-systemd_verify_CFLAGS = \
- $(AM_CFLAGS) \
- $(SECCOMP_CFLAGS)
-
-systemd_verify_LDADD = \
- libsystemd-core.la \
- $(RT_LIBS)
-
-# ------------------------------------------------------------------------------
-
manual_tests += \
test-ns \
test-loopback \
@@ -1738,11 +1724,19 @@ endif
# ------------------------------------------------------------------------------
systemd_analyze_SOURCES = \
- src/analyze/analyze.c
+ src/analyze/analyze.c \
+ src/analyze/analyze-verify.c \
+ src/analyze/analyze-verify.h
+
+systemd_verify_CFLAGS = \
+ $(AM_CFLAGS) \
+ $(SECCOMP_CFLAGS)
systemd_analyze_LDADD = \
+ libsystemd-core.la \
libsystemd-internal.la \
- libsystemd-shared.la
+ libsystemd-shared.la \
+ $(RT_LIBS)
# ------------------------------------------------------------------------------
systemd_initctl_SOURCES = \
diff --git a/src/analyze/analyze-verify.c b/src/analyze/analyze-verify.c
new file mode 100644
index 0000000..5b16b6c
--- /dev/null
+++ b/src/analyze/analyze-verify.c
@@ -0,0 +1,280 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+ This file is part of systemd.
+
+ Copyright 2014 Zbigniew JÄdrzejewski-Szmek
+
+ systemd is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ systemd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <stdlib.h>
+#include <getopt.h>
+
+#include "manager.h"
+#include "bus-util.h"
+#include "log.h"
+#include "strv.h"
+#include "build.h"
+#include "pager.h"
+#include "analyze-verify.h"
+
+static int generate_path(char **var, char **filenames) {
+ char **filename;
+
+ _cleanup_strv_free_ char **ans = NULL;
+ int r;
+
+ STRV_FOREACH(filename, filenames) {
+ char *t;
+
+ t = dirname_malloc(*filename);
+ if (!t)
+ return -ENOMEM;
+
+ r = strv_consume(&ans, t);
+ if (r < 0)
+ return r;
+ }
+
+ assert_se(strv_uniq(ans));
+
+ r = strv_extend(&ans, "");
+ if (r < 0)
+ return r;
+
+ *var = strv_join(ans, ":");
+ if (!*var)
+ return -ENOMEM;
+
+ return 0;
+}
+
+static int verify_socket(Unit *u) {
+ int r;
+
+ assert(u);
+
+ if (u->type != UNIT_SOCKET)
+ return 0;
+
+ /* Cannot run this without the service being around */
+
+ /* This makes sure instance is created if necessary. */
+ r = socket_instantiate_service(SOCKET(u));
+ if (r < 0) {
+ log_error_unit(u->id, "Socket %s cannot be started, failed to create instance.",
+ u->id);
+ return r;
+ }
+
+ /* This checks both type of sockets */
+ if (UNIT_ISSET(SOCKET(u)->service)) {
+ Service *service;
+
+ service = SERVICE(UNIT_DEREF(SOCKET(u)->service));
+ log_debug_unit(u->id, "%s uses %s", u->id, UNIT(service)->id);
+
+ if (UNIT(service)->load_state != UNIT_LOADED) {
+ log_error_unit(u->id, "Service %s not loaded, %s cannot be started.",
+ UNIT(service)->id, u->id);
+ return -ENOENT;
+ }
+ }
+
+ return 0;
+}
+
+static int verify_executable(Unit *u, ExecCommand *exec) {
+ if (exec == NULL)
+ return 0;
+
+ if (access(exec->path, X_OK) < 0) {
+ log_error_unit(u->id, "%s: command %s is not executable: %m",
+ u->id, exec->path);
+ return -errno;
+ }
+
+ return 0;
+}
+
+static int verify_executables(Unit *u) {
+ ExecCommand *exec;
+ int r = 0, k;
+ unsigned i;
+
+ assert(u);
+
+ exec = u->type == UNIT_SOCKET ? SOCKET(u)->control_command :
+ u->type == UNIT_MOUNT ? MOUNT(u)->control_command :
+ u->type == UNIT_SWAP ? SWAP(u)->control_command : NULL;
+ k = verify_executable(u, exec);
+ if (k < 0 && r == 0)
+ r = k;
+
+ if (u->type == UNIT_SERVICE)
+ for (i = 0; i < ELEMENTSOF(SERVICE(u)->exec_command); i++) {
+ k = verify_executable(u, SERVICE(u)->exec_command[i]);
+ if (k < 0 && r == 0)
+ r = k;
+ }
+
+ if (u->type == UNIT_SOCKET)
+ for (i = 0; i < ELEMENTSOF(SOCKET(u)->exec_command); i++) {
+ k = verify_executable(u, SOCKET(u)->exec_command[i]);
+ if (k < 0 && r == 0)
+ r = k;
+ }
+
+ return r;
+}
+
+static int verify_documentation(Unit *u, bool check_man) {
+ char **p;
+ int r = 0, k;
+
+ STRV_FOREACH(p, u->documentation) {
+ log_debug_unit(u->id, "%s: found documentation item %s.", u->id, *p);
+ if (check_man && startswith(*p, "man:")) {
+ k = show_man_page(*p + 4, true);
+ if (k != 0) {
+ if (k < 0)
+ log_error_unit(u->id, "%s: can't show %s: %s",
+ u->id, *p, strerror(-r));
+ else {
+ log_error_unit(u->id, "%s: man %s command failed with code %d",
+ u->id, *p + 4, k);
+ k = -ENOEXEC;
+ }
+ if (r == 0)
+ r = k;
+ }
+ }
+ }
+
+ /* Check remote URLs? */
+
+ return r;
+}
+
+static int verify_unit(Unit *u, bool check_man) {
+ _cleanup_bus_error_free_ sd_bus_error err = SD_BUS_ERROR_NULL;
+ Job *j;
+ int r, k;
+
+ assert(u);
+
+ if (log_get_max_level() >= LOG_DEBUG)
+ unit_dump(u, stdout, "\t");
+
+ log_debug_unit(u->id, "Creating %s/start job", u->id);
+ r = manager_add_job(u->manager, JOB_START, u, JOB_REPLACE, false, &err, &j);
+ if (sd_bus_error_is_set(&err))
+ log_error_unit(u->id, "Error: %s: %s",
+ err.name, err.message);
+ if (r < 0)
+ log_error_unit(u->id, "Failed to create %s/start: %s",
+ u->id, strerror(-r));
+
+ k = verify_socket(u);
+ if (k < 0 && r == 0)
+ r = k;
+
+ k = verify_executables(u);
+ if (k < 0 && r == 0)
+ r = k;
+
+ k = verify_documentation(u, check_man);
+ if (k < 0 && r == 0)
+ r = k;
+
+ return r;
+}
+
+int verify_units(char **filenames, SystemdRunningAs running_as, bool check_man) {
+ _cleanup_bus_error_free_ sd_bus_error err = SD_BUS_ERROR_NULL;
+ Manager *m = NULL;
+ FILE *serial = NULL;
+ FDSet *fdset = NULL;
+
+ _cleanup_free_ char *var = NULL;
+
+ char **filename;
+ int r = 0, k;
+
+ Unit *units[strv_length(filenames)];
+ int i, count = 0;
+
+ if (strv_isempty(filenames))
+ return 0;
+
+ /* set the path */
+ r = generate_path(&var, filenames);
+ if (r < 0) {
+ log_error("Failed to generate unit load path: %s", strerror(-r));
+ return r;
+ }
+
+ assert_se(set_unit_path(var) >= 0);
+
+ r = manager_new(running_as, true, &m);
+ if (r < 0) {
+ log_error("Failed to initalize manager: %s", strerror(-r));
+ return r;
+ }
+
+ log_debug("Starting manager...");
+
+ r = manager_startup(m, serial, fdset);
+ if (r < 0) {
+ log_error("Failed to start manager: %s", strerror(-r));
+ goto finish;
+ }
+
+ manager_clear_jobs(m);
+
+ log_debug("Loading remaining units from the command line...");
+
+ STRV_FOREACH(filename, filenames) {
+ char fname[UNIT_NAME_MAX + 2 + 1] = "./";
+
+ log_debug("Handling %s...", *filename);
+
+ /* manager_load_unit does not like pure basenames, so prepend
+ * the local directory, but only for valid names. manager_load_unit
+ * will print the error for other ones. */
+ if (!strchr(*filename, '/') && strlen(*filename) <= UNIT_NAME_MAX) {
+ strncat(fname + 2, *filename, UNIT_NAME_MAX);
+ k = manager_load_unit(m, NULL, fname, &err, &units[count]);
+ } else
+ k = manager_load_unit(m, NULL, *filename, &err, &units[count]);
+ if (k < 0) {
+ log_error("Failed to load %s: %s", *filename, strerror(-k));
+ if (r == 0)
+ r = k;
+ } else
+ count ++;
+ }
+
+ for (i = 0; i < count; i++) {
+ k = verify_unit(units[i], check_man);
+ if (k < 0 && r == 0)
+ r = k;
+ }
+
+finish:
+ manager_free(m);
+
+ return r;
+}
diff --git a/src/analyze/analyze-verify.h b/src/analyze/analyze-verify.h
new file mode 100644
index 0000000..5c86d98
--- /dev/null
+++ b/src/analyze/analyze-verify.h
@@ -0,0 +1,26 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+ This file is part of systemd.
+
+ Copyright 2014 Zbigniew JÄdrzejewski-Szmek
+
+ systemd is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ systemd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <stdbool.h>
+
+#include "path-lookup.h"
+
+int verify_units(char **filenames, SystemdRunningAs running_as, bool check_man);
diff --git a/src/analyze/analyze.c b/src/analyze/analyze.c
index 0a4190c..66e2aab 100644
--- a/src/analyze/analyze.c
+++ b/src/analyze/analyze.c
@@ -41,6 +41,7 @@
#include "special.h"
#include "hashmap.h"
#include "pager.h"
+#include "analyze-verify.h"
#define SCALE_X (0.1 / 1000.0) /* pixels per us */
#define SCALE_Y (20.0)
@@ -74,6 +75,7 @@ static bool arg_no_pager = false;
static BusTransport arg_transport = BUS_TRANSPORT_LOCAL;
static char *arg_host = NULL;
static bool arg_user = false;
+static bool arg_man = true;
struct boot_times {
usec_t firmware_time;
@@ -1178,17 +1180,17 @@ static int set_log_level(sd_bus *bus, char **args) {
return 0;
}
-static int help(void) {
+static void help(void) {
pager_open_if_enabled();
printf("%s [OPTIONS...] {COMMAND} ...\n\n"
- "Process systemd profiling information.\n\n"
+ "Profile systemd, show unit dependencies, check unit files.\n\n"
" -h --help Show this help\n"
" --version Show package version\n"
" --no-pager Do not pipe output into a pager\n"
- " --system Connect to system manager\n"
- " --user Connect to user manager\n"
+ " --system Operate on system systemd instance\n"
+ " --user Operate on user systemd instance\n"
" -H --host=[USER@]HOST Operate on remote host\n"
" -M --machine=CONTAINER Operate on local container\n"
" --order When generating a dependency graph, show only order\n"
@@ -1200,6 +1202,7 @@ static int help(void) {
" services, which finished TIMESPAN earlier, than the\n"
" latest in the branch. The unit of TIMESPAN is seconds\n"
" unless specified with a different unit, i.e. 50ms\n\n"
+ " --no-man Do not check for existence of man pages\n"
"Commands:\n"
" time Print time spent in the kernel before reaching userspace\n"
" blame Print list of running units ordered by time to init\n"
@@ -1207,14 +1210,13 @@ static int help(void) {
" plot Output SVG graphic showing service initialization\n"
" dot Output dependency graph in dot(1) format\n"
" set-log-level LEVEL Set logging threshold for systemd\n"
- " dump Output state serialization of service manager\n",
- program_invocation_short_name);
+ " dump Output state serialization of service manager\n"
+ " verify Check unit files for correctness\n"
+ , program_invocation_short_name);
/* When updating this list, including descriptions, apply
- * changes to shell-completion/bash/systemd and
- * shell-completion/systemd-zsh-completion.zsh too. */
-
- return 0;
+ * changes to shell-completion/bash/systemd-analyze and
+ * shell-completion/zsh/_systemd-analyze too. */
}
static int parse_argv(int argc, char *argv[]) {
@@ -1227,7 +1229,8 @@ static int parse_argv(int argc, char *argv[]) {
ARG_DOT_FROM_PATTERN,
ARG_DOT_TO_PATTERN,
ARG_FUZZ,
- ARG_NO_PAGER
+ ARG_NO_PAGER,
+ ARG_NO_MAN,
};
static const struct option options[] = {
@@ -1251,12 +1254,15 @@ static int parse_argv(int argc, char *argv[]) {
assert(argc >= 0);
assert(argv);
+ opterr = 0;
+
while ((c = getopt_long(argc, argv, "hH:M:", options, NULL)) >= 0) {
switch (c) {
case 'h':
- return help();
+ help();
+ return 0;
case ARG_VERSION:
puts(PACKAGE_STRING);
@@ -1311,19 +1317,27 @@ static int parse_argv(int argc, char *argv[]) {
arg_host = optarg;
break;
+ case ARG_NO_MAN:
+ arg_man = false;
+ break;
+
case '?':
+ log_error("Unknown option %s.", argv[optind-1]);
+ return -EINVAL;
+
+ case ':':
+ log_error("Missing argument to %s.", argv[optind-1]);
return -EINVAL;
default:
- assert_not_reached("Unhandled option");
+ assert_not_reached("Unhandled option code.");
}
}
- return 1;
+ return 1; /* work to do */
}
int main(int argc, char *argv[]) {
- _cleanup_bus_unref_ sd_bus *bus = NULL;
int r;
setlocale(LC_ALL, "");
@@ -1335,28 +1349,36 @@ int main(int argc, char *argv[]) {
if (r <= 0)
goto finish;
- r = bus_open_transport_systemd(arg_transport, arg_host, arg_user, &bus);
- if (r < 0) {
- log_error("Failed to create bus connection: %s", strerror(-r));
- goto finish;
- }
+ if (streq(argv[optind], "verify"))
+ r = verify_units(argv+optind+1,
+ arg_user ? SYSTEMD_USER : SYSTEMD_SYSTEM,
+ arg_man);
+ else {
+ _cleanup_bus_unref_ sd_bus *bus = NULL;
+
+ r = bus_open_transport_systemd(arg_transport, arg_host, arg_user, &bus);
+ if (r < 0) {
+ log_error("Failed to create bus connection: %s", strerror(-r));
+ goto finish;
+ }
- if (!argv[optind] || streq(argv[optind], "time"))
- r = analyze_time(bus);
- else if (streq(argv[optind], "blame"))
- r = analyze_blame(bus);
- else if (streq(argv[optind], "critical-chain"))
- r = analyze_critical_chain(bus, argv+optind+1);
- else if (streq(argv[optind], "plot"))
- r = analyze_plot(bus);
- else if (streq(argv[optind], "dot"))
- r = dot(bus, argv+optind+1);
- else if (streq(argv[optind], "dump"))
- r = dump(bus, argv+optind+1);
- else if (streq(argv[optind], "set-log-level"))
- r = set_log_level(bus, argv+optind+1);
- else
- log_error("Unknown operation '%s'.", argv[optind]);
+ if (!argv[optind] || streq(argv[optind], "time"))
+ r = analyze_time(bus);
+ else if (streq(argv[optind], "blame"))
+ r = analyze_blame(bus);
+ else if (streq(argv[optind], "critical-chain"))
+ r = analyze_critical_chain(bus, argv+optind+1);
+ else if (streq(argv[optind], "plot"))
+ r = analyze_plot(bus);
+ else if (streq(argv[optind], "dot"))
+ r = dot(bus, argv+optind+1);
+ else if (streq(argv[optind], "dump"))
+ r = dump(bus, argv+optind+1);
+ else if (streq(argv[optind], "set-log-level"))
+ r = set_log_level(bus, argv+optind+1);
+ else
+ log_error("Unknown operation '%s'.", argv[optind]);
+ }
finish:
pager_close();
diff --git a/src/shared/path-lookup.c b/src/shared/path-lookup.c
index 7a715b7..40fb0b8 100644
--- a/src/shared/path-lookup.c
+++ b/src/shared/path-lookup.c
@@ -212,7 +212,7 @@ int lookup_paths_init(
if (!p->unit_path || append) {
/* Let's figure something out. */
- char **unit_path;
+ _cleanup_strv_free_ char **unit_path;
int r;
/* For the user units we include share/ in the search
diff --git a/src/verify/Makefile b/src/verify/Makefile
deleted file mode 120000
index 94aaae2..0000000
--- a/src/verify/Makefile
+++ /dev/null
@@ -1 +0,0 @@
-../../Makefile
\ No newline at end of file
diff --git a/src/verify/verify.c b/src/verify/verify.c
deleted file mode 100644
index c1a3da8..0000000
--- a/src/verify/verify.c
+++ /dev/null
@@ -1,363 +0,0 @@
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
-/***
- This file is part of systemd.
-
- Copyright 2014 Zbigniew JÄdrzejewski-Szmek
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include <stdlib.h>
-#include <getopt.h>
-
-#include "manager.h"
-#include "bus-util.h"
-#include "log.h"
-#include "strv.h"
-#include "build.h"
-#include "pager.h"
-
-SystemdRunningAs arg_running_as = SYSTEMD_SYSTEM;
-bool arg_no_man = false;
-
-static int generate_path(char **var, char **filenames) {
- char **filename;
-
- _cleanup_strv_free_ char **ans = NULL;
- int r;
-
- STRV_FOREACH(filename, filenames) {
- char *t;
-
- t = dirname_malloc(*filename);
- if (!t)
- return -ENOMEM;
-
- r = strv_consume(&ans, t);
- if (r < 0)
- return r;
- }
-
- assert_se(strv_uniq(ans));
-
- r = strv_extend(&ans, "");
- if (r < 0)
- return r;
-
- *var = strv_join(ans, ":");
- if (!*var)
- return -ENOMEM;
-
- return 0;
-}
-
-static int verify_socket(Unit *u) {
- int r;
-
- assert(u);
-
- if (u->type != UNIT_SOCKET)
- return 0;
-
- /* Cannot run this without the service being around */
-
- /* This makes sure instance is created if necessary. */
- r = socket_instantiate_service(SOCKET(u));
- if (r < 0) {
- log_error_unit(u->id, "Socket %s cannot be started, failed to create instance.",
- u->id);
- return r;
- }
-
- /* This checks both type of sockets */
- if (UNIT_ISSET(SOCKET(u)->service)) {
- Service *service;
-
- service = SERVICE(UNIT_DEREF(SOCKET(u)->service));
- log_debug_unit(u->id, "%s uses %s", u->id, UNIT(service)->id);
-
- if (UNIT(service)->load_state != UNIT_LOADED) {
- log_error_unit(u->id, "Service %s not loaded, %s cannot be started.",
- UNIT(service)->id, u->id);
- return -ENOENT;
- }
- }
-
- return 0;
-}
-
-static int verify_executable(Unit *u, ExecCommand *exec) {
- if (exec == NULL)
- return 0;
-
- if (access(exec->path, X_OK) < 0) {
- log_error_unit(u->id, "%s: command %s is not executable: %m",
- u->id, exec->path);
- return -errno;
- }
-
- return 0;
-}
-
-static int verify_executables(Unit *u) {
- ExecCommand *exec;
- int r = 0, k;
- unsigned i;
-
- assert(u);
-
- exec = u->type == UNIT_SOCKET ? SOCKET(u)->control_command :
- u->type == UNIT_MOUNT ? MOUNT(u)->control_command :
- u->type == UNIT_SWAP ? SWAP(u)->control_command : NULL;
- k = verify_executable(u, exec);
- if (k < 0 && r == 0)
- r = k;
-
- if (u->type == UNIT_SERVICE)
- for (i = 0; i < ELEMENTSOF(SERVICE(u)->exec_command); i++) {
- k = verify_executable(u, SERVICE(u)->exec_command[i]);
- if (k < 0 && r == 0)
- r = k;
- }
-
- if (u->type == UNIT_SOCKET)
- for (i = 0; i < ELEMENTSOF(SOCKET(u)->exec_command); i++) {
- k = verify_executable(u, SOCKET(u)->exec_command[i]);
- if (k < 0 && r == 0)
- r = k;
- }
-
- return r;
-}
-
-static int verify_documentation(Unit *u) {
- char **p;
- int r = 0, k;
-
- if (arg_no_man)
- return 0;
-
- STRV_FOREACH(p, u->documentation) {
- log_debug_unit(u->id, "%s: found documentation item %s.", u->id, *p);
- if (startswith(*p, "man:")) {
- k = show_man_page(*p + 4, true);
- if (k != 0) {
- if (k < 0)
- log_error_unit(u->id, "%s: can't show %s: %s",
- u->id, *p, strerror(-r));
- else {
- log_error_unit(u->id, "%s: man %s command failed with code %d",
- u->id, *p + 4, k);
- k = -ENOEXEC;
- }
- if (r == 0)
- r = k;
- }
- }
- }
-
- /* Check remote URLs? */
-
- return r;
-}
-
-static int test_unit(Unit *u) {
- _cleanup_bus_error_free_ sd_bus_error err = SD_BUS_ERROR_NULL;
- Job *j;
- int r, k;
-
- assert(u);
-
- if (log_get_max_level() >= LOG_DEBUG)
- unit_dump(u, stdout, "\t");
-
- log_debug_unit(u->id, "Creating %s/start job", u->id);
- r = manager_add_job(u->manager, JOB_START, u, JOB_REPLACE, false, &err, &j);
- if (sd_bus_error_is_set(&err))
- log_error_unit(u->id, "Error: %s: %s",
- err.name, err.message);
- if (r < 0)
- log_error_unit(u->id, "Failed to create %s/start: %s",
- u->id, strerror(-r));
-
- k = verify_socket(u);
- if (k < 0 && r == 0)
- r = k;
-
- k = verify_executables(u);
- if (k < 0 && r == 0)
- r = k;
-
- k = verify_documentation(u);
- if (k < 0 && r == 0)
- r = k;
-
- return r;
-}
-
-static int test_units(char **filenames) {
- _cleanup_bus_error_free_ sd_bus_error err = SD_BUS_ERROR_NULL;
- Manager *m = NULL;
- FILE *serial = NULL;
- FDSet *fdset = NULL;
-
- _cleanup_free_ char *var;
-
- char **filename;
- int r = 0, k;
-
- Unit *units[strv_length(filenames)];
- int i, count = 0;
-
- /* set the path */
- r = generate_path(&var, filenames);
- if (r < 0) {
- log_error("Failed to generate unit load path: %s", strerror(-r));
- return r;
- }
-
- assert_se(set_unit_path(var) >= 0);
-
- r = manager_new(arg_running_as, true, &m);
- if (r < 0) {
- log_error("Failed to initalize manager: %s", strerror(-r));
- return r;
- }
-
- log_debug("Starting manager...");
-
- r = manager_startup(m, serial, fdset);
- if (r < 0) {
- log_error("Failed to start manager: %s", strerror(-r));
- goto finish;
- }
-
- manager_clear_jobs(m);
-
- log_debug("Loading remaining units from the command line...");
-
- STRV_FOREACH(filename, filenames) {
- log_debug("Handling %s...", *filename);
-
- k = manager_load_unit(m, NULL, *filename, &err, &units[count]);
- if (k < 0) {
- log_error("Failed to load %s: %s", *filename, strerror(-r));
- if (r == 0)
- r = k;
- }
-
- count ++;
- }
-
- for (i = 0; i < count; i++) {
- k = test_unit(units[i]);
- if (k < 0 && r == 0)
- r = k;
- }
-
-finish:
- manager_free(m);
-
- return r;
-}
-
-static void help(void) {
- printf("%s [OPTIONS...] {COMMAND} ...\n\n"
- "Check if unit files can be correctly loaded.\n\n"
- " -h --help Show this help\n"
- " --version Show package version\n"
- " --system Test system units\n"
- " --user Test user units\n"
- " --no-man Do not check for existence of man pages\n"
- , program_invocation_short_name);
-}
-
-static int parse_argv(int argc, char *argv[]) {
- enum {
- ARG_VERSION = 0x100,
- ARG_USER,
- ARG_SYSTEM,
- ARG_NO_MAN,
- };
-
- static const struct option options[] = {
- { "help", no_argument, NULL, 'h' },
- { "version", no_argument, NULL, ARG_VERSION },
- { "user", no_argument, NULL, ARG_USER },
- { "system", no_argument, NULL, ARG_SYSTEM },
- {}
- };
-
- int c;
-
- assert(argc >= 1);
- assert(argv);
-
- opterr = 0;
-
- while ((c = getopt_long(argc, argv, ":h", options, NULL)) >= 0)
- switch (c) {
-
- case 'h':
- help();
- return 0;
-
- case ARG_VERSION:
- puts(PACKAGE_STRING);
- puts(SYSTEMD_FEATURES);
- return 0;
-
- case ARG_USER:
- arg_running_as = SYSTEMD_USER;
- break;
-
- case ARG_SYSTEM:
- arg_running_as = SYSTEMD_SYSTEM;
- break;
-
- case ARG_NO_MAN:
- arg_no_man = true;
- break;
-
- case '?':
- log_error("Unknown option %s.", argv[optind-1]);
- return -EINVAL;
-
- case ':':
- log_error("Missing argument to %s.", argv[optind-1]);
- return -EINVAL;
-
- default:
- assert_not_reached("Unhandled option code.");
- }
-
- return 1; /* work to do */
-}
-
-int main(int argc, char *argv[]) {
- int r;
-
- log_parse_environment();
- log_open();
-
- r = parse_argv(argc, argv);
- if (r <= 0)
- goto finish;
-
- r = test_units(argv + optind);
-
-finish:
- return r >= 0 ? EXIT_SUCCESS : EXIT_FAILURE;
-}
commit 1a40a3393e904fe4683f6d2b2450cfbd94a34000
Author: Zbigniew JÄdrzejewski-Szmek <zbyszek at in.waw.pl>
Date: Mon Jul 21 21:07:19 2014 -0400
configure: add -Wno-typedef-redefinition
Message-ID: <CAJ+BJsz9Qy-JU25dUuGT2n0LMNzcOpoJNGNtbf_boSuT_6hONw at mail.gmail.com>
diff --git a/configure.ac b/configure.ac
index 8cbf764..43b6eef 100644
--- a/configure.ac
+++ b/configure.ac
@@ -183,6 +183,7 @@ CC_CHECK_FLAGS_APPEND([with_cflags], [CFLAGS], [\
-Wno-unused-parameter \
-Wno-missing-field-initializers \
-Wno-unused-result \
+ -Wno-typedef-redefinition \
-Werror=overflow \
-Wdate-time \
-Wnested-externs \
commit 6589d0dba2b1ccf2406db527c2c1b51c7143e117
Author: Jean-André Santoni <jean.andre.santoni at gmail.com>
Date: Mon Jul 21 21:04:44 2014 -0400
Add IFLA_VTI defines to missing.h
diff --git a/configure.ac b/configure.ac
index 6f888a2..8cbf764 100644
--- a/configure.ac
+++ b/configure.ac
@@ -311,6 +311,7 @@ AC_CHECK_DECLS([gettid, pivot_root, name_to_handle_at, setns, LO_FLAGS_PARTSCAN]
]])
AC_CHECK_DECLS([IFLA_MACVLAN_FLAGS,
+ IFLA_VTI_REMOTE,
IFLA_PHYS_PORT_ID,
IFLA_BOND_AD_INFO,
IFLA_VLAN_PROTOCOL,
diff --git a/src/shared/missing.h b/src/shared/missing.h
index 818d704..2985285 100644
--- a/src/shared/missing.h
+++ b/src/shared/missing.h
@@ -380,6 +380,18 @@ static inline int setns(int fd, int nstype) {
#define IFLA_MACVLAN_MAX (__IFLA_MACVLAN_MAX - 1)
#endif
+#if !HAVE_DECL_IFLA_VTI_REMOTE
+#define IFLA_VTI_UNSPEC 0
+#define IFLA_VTI_LINK 1
+#define IFLA_VTI_IKEY 2
+#define IFLA_VTI_OKEY 3
+#define IFLA_VTI_LOCAL 4
+#define IFLA_VTI_REMOTE 5
+#define __IFLA_VTI_MAX 6
+
+#define IFLA_VTI_MAX (__IFLA_VTI_MAX - 1)
+#endif
+
#if !HAVE_DECL_IFLA_PHYS_PORT_ID
#undef IFLA_PROMISCUITY
#define IFLA_PROMISCUITY 30
commit 7dbb1d08f66cd44b1296be3ee8e3629b989e19a8
Author: Zbigniew JÄdrzejewski-Szmek <zbyszek at in.waw.pl>
Date: Mon Jul 21 20:56:29 2014 -0400
update-done: set proper selinux context for .updated
https://bugzilla.redhat.com/show_bug.cgi?id=1121806
diff --git a/Makefile.am b/Makefile.am
index 1e4cfb3..1cb7712 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1771,6 +1771,7 @@ systemd_update_done_SOURCES = \
systemd_update_done_LDADD = \
libsystemd-internal.la \
+ libsystemd-label.la \
libsystemd-shared.la
# ------------------------------------------------------------------------------
diff --git a/src/update-done/update-done.c b/src/update-done/update-done.c
index 10ba85c..b199a68 100644
--- a/src/update-done/update-done.c
+++ b/src/update-done/update-done.c
@@ -20,6 +20,7 @@
***/
#include "util.h"
+#include "label.h"
static int apply_timestamp(const char *path, struct timespec *ts) {
struct timespec twice[2];
@@ -51,10 +52,20 @@ static int apply_timestamp(const char *path, struct timespec *ts) {
} else if (errno == ENOENT) {
_cleanup_close_ int fd = -1;
+ int r;
/* The timestamp file doesn't exist yet? Then let's create it. */
+ r = label_context_set(path, S_IFREG);
+ if (r < 0) {
+ log_error("Failed to set SELinux context for %s: %s",
+ path, strerror(-r));
+ return r;
+ }
+
fd = open(path, O_CREAT|O_EXCL|O_WRONLY|O_TRUNC|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW, 0644);
+ label_context_clear();
+
if (fd < 0) {
if (errno == EROFS) {
@@ -83,7 +94,7 @@ static int apply_timestamp(const char *path, struct timespec *ts) {
int main(int argc, char *argv[]) {
struct stat st;
- int r, q;
+ int r, q = 0;
log_set_target(LOG_TARGET_AUTO);
log_parse_environment();
@@ -94,11 +105,15 @@ int main(int argc, char *argv[]) {
return EXIT_FAILURE;
}
- r = apply_timestamp("/etc/.updated", &st.st_mtim);
+ r = label_init(NULL);
+ if (r < 0) {
+ log_error("SELinux setup failed: %s", strerror(-r));
+ goto finish;
+ }
+ r = apply_timestamp("/etc/.updated", &st.st_mtim);
q = apply_timestamp("/var/.updated", &st.st_mtim);
- if (q < 0 && r == 0)
- r = q;
- return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
+finish:
+ return r < 0 || q < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
}
commit 9f1c19405a1ccaf59dcc8c32c13a1619541189ad
Author: Zbigniew JÄdrzejewski-Szmek <zbyszek at in.waw.pl>
Date: Mon Jul 21 20:41:19 2014 -0400
sysusers: fix selinux context of backup files
Also, fix fopen_temporary_label to set proper context. By chance,
all users so far used the same context, so the error didn't matter.
Also, check return value from label_init().
https://bugzilla.redhat.com/show_bug.cgi?id=1121806
diff --git a/src/shared/fileio-label.c b/src/shared/fileio-label.c
index 417ca56..c3def3c 100644
--- a/src/shared/fileio-label.c
+++ b/src/shared/fileio-label.c
@@ -59,7 +59,7 @@ int fopen_temporary_label(const char *target,
const char *path, FILE **f, char **temp_path) {
int r;
- r = label_context_set("/etc/passwd", S_IFREG);
+ r = label_context_set(target, S_IFREG);
if (r < 0)
return r;
diff --git a/src/sysusers/sysusers.c b/src/sysusers/sysusers.c
index d679394..b7c1609 100644
--- a/src/sysusers/sysusers.c
+++ b/src/sysusers/sysusers.c
@@ -195,8 +195,9 @@ static int load_group_database(void) {
return 0;
}
-static int make_backup(const char *x) {
- _cleanup_close_ int src = -1, dst = -1;
+static int make_backup(const char *target, const char *x) {
+ _cleanup_close_ int src = -1;
+ _cleanup_fclose_ FILE *dst = NULL;
char *backup, *temp;
struct timespec ts[2];
struct stat st;
@@ -213,30 +214,30 @@ static int make_backup(const char *x) {
if (fstat(src, &st) < 0)
return -errno;
- temp = strappenda(x, ".XXXXXX");
- dst = mkostemp_safe(temp, O_WRONLY|O_CLOEXEC|O_NOCTTY);
- if (dst < 0)
- return dst;
+ r = fopen_temporary_label(target, x, &dst, &temp);
+ if (r < 0)
+ return r;
- r = copy_bytes(src, dst, (off_t) -1);
+ r = copy_bytes(src, fileno(dst), (off_t) -1);
if (r < 0)
goto fail;
+ /* Don't fail on chmod() or chown(). If it stays owned by us
+ * and/or unreadable by others, then it isn't too bad... */
+
+ backup = strappenda(x, "-");
+
/* Copy over the access mask */
- if (fchmod(dst, st.st_mode & 07777) < 0) {
- r = -errno;
- goto fail;
- }
+ if (fchmod(fileno(dst), st.st_mode & 07777) < 0)
+ log_warning("Failed to change mode on %s: %m", backup);
- /* Don't fail on chmod(). If it stays owned by us, then it
- * isn't too bad... */
- fchown(dst, st.st_uid, st.st_gid);
+ if (fchown(fileno(dst), st.st_uid, st.st_gid)< 0)
+ log_warning("Failed to change ownership of %s: %m", backup);
ts[0] = st.st_atim;
ts[1] = st.st_mtim;
- futimens(dst, ts);
+ futimens(fileno(dst), ts);
- backup = strappenda(x, "-");
if (rename(temp, backup) < 0)
goto fail;
@@ -469,13 +470,13 @@ static int write_files(void) {
/* Make a backup of the old files */
if (group && group_changed) {
- r = make_backup(group_path);
+ r = make_backup("/etc/group", group_path);
if (r < 0)
goto finish;
}
if (passwd) {
- r = make_backup(passwd_path);
+ r = make_backup("/etc/passwd", passwd_path);
if (r < 0)
goto finish;
}
@@ -1493,9 +1494,11 @@ int main(int argc, char *argv[]) {
umask(0022);
- label_init(NULL);
-
- r = 0;
+ r = label_init(NULL);
+ if (r < 0) {
+ log_error("SELinux setup failed: %s", strerror(-r));
+ goto finish;
+ }
if (optind < argc) {
int j;
More information about the systemd-commits
mailing list