summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--Makefile-man.am12
-rw-r--r--Makefile.am16
-rw-r--r--NEWS29
-rw-r--r--coccinelle/strempty.cocci10
-rw-r--r--man/kernel-command-line.xml3
-rw-r--r--man/machine-id.xml2
-rw-r--r--man/sd_bus_path_encode.xml38
-rw-r--r--man/systemctl.xml50
-rw-r--r--man/systemd-journald.service.xml5
-rw-r--r--man/systemd-machine-id-commit.service.xml57
-rw-r--r--man/systemd-machine-id-commit.xml123
-rw-r--r--man/systemd-machine-id-setup.xml100
-rw-r--r--man/systemd-notify.xml15
-rw-r--r--man/systemd-system.conf.xml3
-rw-r--r--man/systemd.exec.xml23
-rw-r--r--man/systemd.xml104
-rw-r--r--src/activate/activate.c13
-rw-r--r--src/analyze/analyze.c28
-rw-r--r--src/basic/prioq.c12
-rw-r--r--src/basic/selinux-util.c10
-rw-r--r--src/basic/selinux-util.h6
-rw-r--r--src/basic/strv.c25
-rw-r--r--src/basic/strv.h4
-rw-r--r--src/basic/terminal-util.c2
-rw-r--r--src/basic/util.c95
-rw-r--r--src/basic/util.h8
-rw-r--r--src/binfmt/binfmt.c19
-rw-r--r--src/boot/bootctl.c32
-rw-r--r--src/bus-proxyd/bus-proxyd.c28
-rw-r--r--src/bus-proxyd/stdio-bridge.c20
-rw-r--r--src/cgls/cgls.c26
-rw-r--r--src/cgroups-agent/cgroups-agent.c2
-rw-r--r--src/cgtop/cgtop.c34
-rw-r--r--src/core/dbus-execute.c87
-rw-r--r--src/core/execute.c21
-rw-r--r--src/core/execute.h1
-rw-r--r--src/core/load-fragment-gperf.gperf.m42
-rw-r--r--src/core/load-fragment.c129
-rw-r--r--src/core/load-fragment.h1
-rw-r--r--src/core/main.c428
-rw-r--r--src/core/manager.c66
-rw-r--r--src/core/manager.h6
-rw-r--r--src/core/namespace.c44
-rw-r--r--src/core/selinux-setup.c6
-rw-r--r--src/core/shutdown.c1
-rw-r--r--src/core/socket.c255
-rw-r--r--src/core/system.conf5
-rw-r--r--src/core/unit.c6
-rw-r--r--src/delta/delta.c17
-rw-r--r--src/detect-virt/detect-virt.c20
-rw-r--r--src/escape/escape.c9
-rw-r--r--src/firstboot/firstboot.c20
-rw-r--r--src/fsck/fsck.c2
-rw-r--r--src/hostname/hostnamectl.c20
-rw-r--r--src/hwdb/hwdb.c20
-rw-r--r--src/import/export.c16
-rw-r--r--src/import/import.c16
-rw-r--r--src/import/importd.c8
-rw-r--r--src/import/pull.c16
-rw-r--r--src/initctl/initctl.c2
-rw-r--r--src/journal-remote/journal-gatewayd.c16
-rw-r--r--src/journal-remote/journal-remote.c27
-rw-r--r--src/journal-remote/journal-upload.c20
-rw-r--r--src/journal/cat.c41
-rw-r--r--src/journal/coredumpctl.c26
-rw-r--r--src/journal/journal-send.c26
-rw-r--r--src/journal/journalctl.c59
-rw-r--r--src/libsystemd-network/sd-pppoe.c6
-rw-r--r--src/libsystemd/libsystemd.sym2
-rw-r--r--src/libsystemd/sd-bus/bus-container.c11
-rw-r--r--src/libsystemd/sd-bus/busctl.c23
-rw-r--r--src/libsystemd/sd-bus/sd-bus.c165
-rw-r--r--src/libsystemd/sd-bus/test-bus-marshal.c31
-rw-r--r--src/libsystemd/sd-daemon/sd-daemon.c7
-rw-r--r--src/libsystemd/sd-event/sd-event.c30
-rw-r--r--src/libsystemd/sd-hwdb/hwdb-internal.h1
-rw-r--r--src/locale/localectl.c28
-rw-r--r--src/login/inhibit.c16
-rw-r--r--src/login/loginctl.c32
-rw-r--r--src/login/sysfs-show.c2
l---------src/machine-id-commit/Makefile1
-rw-r--r--src/machine-id-commit/machine-id-commit.c107
-rw-r--r--src/machine-id-setup/machine-id-setup-main.c36
-rw-r--r--src/machine/machine-dbus.c5
-rw-r--r--src/machine/machinectl.c54
-rw-r--r--src/modules-load/modules-load.c13
-rw-r--r--src/network/networkctl.c29
-rw-r--r--src/network/networkd-link.c10
-rw-r--r--src/network/networkd-wait-online.c10
-rw-r--r--src/notify/notify.c5
-rw-r--r--src/nspawn/nspawn-expose-ports.c4
-rw-r--r--src/nspawn/nspawn.c14
-rw-r--r--src/path/path.c12
-rw-r--r--src/resolve-host/resolve-host.c13
-rw-r--r--src/run/run.c22
-rw-r--r--src/shared/ask-password-api.h3
-rw-r--r--src/shared/bus-util.c20
-rw-r--r--src/shared/bus-util.h8
-rw-r--r--src/shared/pager.c27
-rw-r--r--src/shared/sysctl-util.c13
-rw-r--r--src/sleep/sleep.c16
-rw-r--r--src/socket-proxy/socket-proxyd.c14
-rw-r--r--src/sysctl/sysctl.c25
-rw-r--r--src/systemctl/systemctl.c1571
-rw-r--r--src/systemd/sd-bus.h2
-rw-r--r--src/sysusers/sysusers.c27
-rw-r--r--src/test/test-strv.c23
-rw-r--r--src/timedate/timedatectl.c18
-rw-r--r--src/tmpfiles/tmpfiles.c49
-rw-r--r--src/tty-ask-password-agent/tty-ask-password-agent.c40
-rw-r--r--src/update-utmp/update-utmp.c21
-rw-r--r--units/systemd-hostnamed.service.in2
-rw-r--r--units/systemd-importd.service.in2
-rw-r--r--units/systemd-journal-remote.service.in2
-rw-r--r--units/systemd-journal-upload.service.in2
-rw-r--r--units/systemd-journald.service.in2
-rw-r--r--units/systemd-localed.service.in2
-rw-r--r--units/systemd-logind.service.in2
-rw-r--r--units/systemd-machine-id-commit.service.in2
-rw-r--r--units/systemd-machined.service.in2
-rw-r--r--units/systemd-networkd.service.m4.in2
-rw-r--r--units/systemd-resolved.service.m4.in2
-rw-r--r--units/systemd-timedated.service.in2
-rw-r--r--units/systemd-timesyncd.service.in2
-rw-r--r--units/systemd-udevd.service.in2
126 files changed, 2568 insertions, 2420 deletions
diff --git a/.gitignore b/.gitignore
index 605d109dfa..6149b01c6c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -96,7 +96,6 @@
/systemd-kmsg-syslogd
/systemd-localed
/systemd-logind
-/systemd-machine-id-commit
/systemd-machine-id-setup
/systemd-machined
/systemd-modules-load
diff --git a/Makefile-man.am b/Makefile-man.am
index 3b8038611b..49586fe04c 100644
--- a/Makefile-man.am
+++ b/Makefile-man.am
@@ -102,7 +102,6 @@ MANPAGES += \
man/systemd-inhibit.1 \
man/systemd-initctl.service.8 \
man/systemd-journald.service.8 \
- man/systemd-machine-id-commit.1 \
man/systemd-machine-id-commit.service.8 \
man/systemd-machine-id-setup.1 \
man/systemd-notify.1 \
@@ -292,6 +291,8 @@ MANPAGES_ALIAS += \
man/sd_bus_open_system_remote.3 \
man/sd_bus_open_user.3 \
man/sd_bus_path_decode.3 \
+ man/sd_bus_path_decode_many.3 \
+ man/sd_bus_path_encode_many.3 \
man/sd_bus_ref.3 \
man/sd_bus_release_name.3 \
man/sd_bus_unref.3 \
@@ -578,6 +579,8 @@ man/sd_bus_open_system_machine.3: man/sd_bus_default.3
man/sd_bus_open_system_remote.3: man/sd_bus_default.3
man/sd_bus_open_user.3: man/sd_bus_default.3
man/sd_bus_path_decode.3: man/sd_bus_path_encode.3
+man/sd_bus_path_decode_many.3: man/sd_bus_path_encode.3
+man/sd_bus_path_encode_many.3: man/sd_bus_path_encode.3
man/sd_bus_ref.3: man/sd_bus_new.3
man/sd_bus_release_name.3: man/sd_bus_request_name.3
man/sd_bus_unref.3: man/sd_bus_new.3
@@ -1124,6 +1127,12 @@ man/sd_bus_open_user.html: man/sd_bus_default.html
man/sd_bus_path_decode.html: man/sd_bus_path_encode.html
$(html-alias)
+man/sd_bus_path_decode_many.html: man/sd_bus_path_encode.html
+ $(html-alias)
+
+man/sd_bus_path_encode_many.html: man/sd_bus_path_encode.html
+ $(html-alias)
+
man/sd_bus_ref.html: man/sd_bus_new.html
$(html-alias)
@@ -2341,7 +2350,6 @@ EXTRA_DIST += \
man/systemd-localed.service.xml \
man/systemd-logind.service.xml \
man/systemd-machine-id-commit.service.xml \
- man/systemd-machine-id-commit.xml \
man/systemd-machine-id-setup.xml \
man/systemd-machined.service.xml \
man/systemd-modules-load.service.xml \
diff --git a/Makefile.am b/Makefile.am
index e9ad72333b..6ddc0b74f3 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -397,7 +397,6 @@ rootlibexec_PROGRAMS = \
systemd-remount-fs \
systemd-reply-password \
systemd-fsck \
- systemd-machine-id-commit \
systemd-ac-power \
systemd-sysctl \
systemd-sleep \
@@ -2331,6 +2330,9 @@ systemd_machine_id_setup_SOURCES = \
systemd_machine_id_setup_LDADD = \
libshared.la
+SYSINIT_TARGET_WANTS += \
+ systemd-machine-id-commit.service
+
# ------------------------------------------------------------------------------
systemd_sysctl_SOURCES = \
src/sysctl/sysctl.c
@@ -2353,18 +2355,6 @@ systemd_fsck_LDADD = \
libshared.la
# ------------------------------------------------------------------------------
-systemd_machine_id_commit_SOURCES = \
- src/machine-id-commit/machine-id-commit.c \
- src/core/machine-id-setup.c \
- src/core/machine-id-setup.h
-
-systemd_machine_id_commit_LDADD = \
- libshared.la
-
-SYSINIT_TARGET_WANTS += \
- systemd-machine-id-commit.service
-
-# ------------------------------------------------------------------------------
systemd_ac_power_SOURCES = \
src/ac-power/ac-power.c
diff --git a/NEWS b/NEWS
index 68e46dd0df..03dc5ba2e3 100644
--- a/NEWS
+++ b/NEWS
@@ -31,6 +31,35 @@ CHANGES WITH 227:
assignments and "auto" for picking a free value
automatically.
+ * 'systemctl is-system-running' now returns 'offline' if the
+ system is not booted with systemd. This command can now be
+ used as a substitute for 'systemd-notify --booted'.
+
+ * Watchdog timeouts have been increased to 3 minutes for all
+ in-tree service files. Apparently, disk IO issues are more
+ frequent than we hoped, and user reported >1 minute waiting
+ for disk IO.
+
+ * 'machine-id-commit' functionality has been merged into
+ 'machine-id-setup --commit'. The separate binary has been
+ removed.
+
+ * The WorkingDirectory= directive in unit files may now be
+ set to the special value '~'. In this case, the working
+ directory is set to the home directory of the user configured
+ in User=.
+
+ * A new systemd.crash_reboot=1 kernel command line option has
+ been added that triggers a reboot after crashing. This can
+ also be set through CrashReboot= in systemd.conf.
+
+ * The CrashChVT= configuration file setting is renamed to
+ CrashChangeVT=, following our usual logic of not abbreviating
+ unnecessarily. The old directive is still supported for compat
+ reasons. Also, this directive now takes an integer value
+ between 1 and 63, or a boolean value. The formerly supported
+ '-1' value for disabling stays around for compat reasons.
+
* The PrivateTmp, PrivateDevices, PrivateNetwork,
NoNewPrivileges, TTYPath, WorkingDirectory and RootDirectory
properties can now be set for transient units.
diff --git a/coccinelle/strempty.cocci b/coccinelle/strempty.cocci
new file mode 100644
index 0000000000..e3bd0a1f56
--- /dev/null
+++ b/coccinelle/strempty.cocci
@@ -0,0 +1,10 @@
+@@
+expression s;
+@@
+- s ?: ""
++ strempty(s)
+@@
+expression s;
+@@
+- s ? s : ""
++ strempty(s)
diff --git a/man/kernel-command-line.xml b/man/kernel-command-line.xml
index eb73727027..2f81746b5e 100644
--- a/man/kernel-command-line.xml
+++ b/man/kernel-command-line.xml
@@ -79,8 +79,9 @@
<term><varname>systemd.unit=</varname></term>
<term><varname>rd.systemd.unit=</varname></term>
<term><varname>systemd.dump_core=</varname></term>
- <term><varname>systemd.crash_shell=</varname></term>
<term><varname>systemd.crash_chvt=</varname></term>
+ <term><varname>systemd.crash_shell=</varname></term>
+ <term><varname>systemd.crash_reboot=</varname></term>
<term><varname>systemd.confirm_spawn=</varname></term>
<term><varname>systemd.show_status=</varname></term>
<term><varname>systemd.log_target=</varname></term>
diff --git a/man/machine-id.xml b/man/machine-id.xml
index 92d67a3869..8ce9c46ff1 100644
--- a/man/machine-id.xml
+++ b/man/machine-id.xml
@@ -63,7 +63,7 @@
<para>The machine ID is usually generated from a random source
during system installation and stays constant for all subsequent
boots. Optionally, for stateless systems, it is generated during
- runtime at boot if it is found to be empty.</para>
+ runtime at early boot if it is found to be empty.</para>
<para>The machine ID does not change based on user configuration
or when hardware is replaced.</para>
diff --git a/man/sd_bus_path_encode.xml b/man/sd_bus_path_encode.xml
index 21c22a8f7c..696dfd00ba 100644
--- a/man/sd_bus_path_encode.xml
+++ b/man/sd_bus_path_encode.xml
@@ -44,7 +44,9 @@
<refnamediv>
<refname>sd_bus_path_encode</refname>
+ <refname>sd_bus_path_encode_many</refname>
<refname>sd_bus_path_decode</refname>
+ <refname>sd_bus_path_decode_many</refname>
<refpurpose>Convert an external identifier into an object path and back</refpurpose>
</refnamediv>
@@ -61,11 +63,25 @@
</funcprototype>
<funcprototype>
+ <funcdef>int <function>sd_bus_path_encode_many</function></funcdef>
+ <paramdef>char **<parameter>out</parameter></paramdef>
+ <paramdef>const char *<parameter>path_template</parameter></paramdef>
+ <paramdef>...</paramdef>
+ </funcprototype>
+
+ <funcprototype>
<funcdef>int <function>sd_bus_path_decode</function></funcdef>
<paramdef>const char *<parameter>path</parameter></paramdef>
<paramdef>const char *<parameter>prefix</parameter></paramdef>
<paramdef>char **<parameter>ret_external_id</parameter></paramdef>
</funcprototype>
+
+ <funcprototype>
+ <funcdef>int <function>sd_bus_path_decode_many</function></funcdef>
+ <paramdef>const char *<parameter>path</parameter></paramdef>
+ <paramdef>const char *<parameter>path_template</parameter></paramdef>
+ <paramdef>...</paramdef>
+ </funcprototype>
</funcsynopsis>
</refsynopsisdiv>
@@ -109,6 +125,28 @@
invalid in a bus object path by <literal>_</literal>, followed by a
hexadecimal value. As a special case, the empty string will be
replaced by a lone <literal>_</literal>.</para>
+
+ <para><function>sd_bus_path_encode_many()</function> works like
+ its counterpart <function>sd_bus_path_encode()</function>, but
+ takes a path-template as argument and encodes multiple labels
+ according to its embedded directives. For each
+ <literal>%</literal> character found in the template, the caller
+ must provide a string via var-args, which will be encoded and
+ embedded at the position of the <literal>%</literal> character.
+ Any other character in the template is copied verbatim into the
+ encoded path.</para>
+
+ <para><function>sd_bus_path_decode_many()</function> does the
+ reverse of <function>sd_bus_path_encode_many()</function>. It
+ decodes the passed object path, according to the given
+ path-template. For each <literal>%</literal> character in the
+ template, the caller must provide an output storage
+ (<literal>char **</literal>) via var-args. The decoded label
+ will be stored there. Each <literal>%</literal> character will
+ only match the current label. It will never match across labels.
+ Furthermore, only a single such directive is allowed per label.
+ If <literal>NULL</literal> is passed as output storage, the
+ label is verified but not returned to the caller.</para>
</refsect1>
<refsect1>
diff --git a/man/systemctl.xml b/man/systemctl.xml
index c1359d1678..9e9ba5a5b6 100644
--- a/man/systemctl.xml
+++ b/man/systemctl.xml
@@ -1120,9 +1120,9 @@ kobject-uevent 1 systemd-udevd-kernel.socket systemd-udevd.service
<tgroup cols='3'>
<thead>
<row>
- <entry>Printed string</entry>
- <entry>Meaning</entry>
- <entry>Return value</entry>
+ <entry>Name</entry>
+ <entry>Description</entry>
+ <entry>Exit Code</entry>
</row>
</thead>
<tbody>
@@ -1137,7 +1137,7 @@ kobject-uevent 1 systemd-udevd-kernel.socket systemd-udevd.service
<row>
<entry><literal>linked</literal></entry>
<entry morerows='1'>Made available through a symlink to the unit file (permanently or just in <filename>/run</filename>).</entry>
- <entry morerows='1'>1</entry>
+ <entry morerows='1'>&gt; 0</entry>
</row>
<row>
<entry><literal>linked-runtime</literal></entry>
@@ -1145,7 +1145,7 @@ kobject-uevent 1 systemd-udevd-kernel.socket systemd-udevd.service
<row>
<entry><literal>masked</literal></entry>
<entry morerows='1'>Disabled entirely (permanently or just in <filename>/run</filename>).</entry>
- <entry morerows='1'>1</entry>
+ <entry morerows='1'>&gt; 0</entry>
</row>
<row>
<entry><literal>masked-runtime</literal></entry>
@@ -1163,7 +1163,7 @@ kobject-uevent 1 systemd-udevd-kernel.socket systemd-udevd.service
<row>
<entry><literal>disabled</literal></entry>
<entry>Unit file is not enabled.</entry>
- <entry>1</entry>
+ <entry>&gt; 0</entry>
</row>
</tbody>
</tgroup>
@@ -1474,22 +1474,25 @@ kobject-uevent 1 systemd-udevd-kernel.socket systemd-udevd.service
<listitem>
<para>Checks whether the system is operational. This
- returns success when the system is fully up and running,
- meaning not in startup, shutdown or maintenance
- mode. Failure is returned otherwise. In addition, the
+ returns success (exit code 0) when the system is fully up
+ and running, specifically not in startup, shutdown or
+ maintenance mode, and with no failed services. Failure is
+ returned otherwise (exit code non-zero). In addition, the
current state is printed in a short string to standard
output, see table below. Use <option>--quiet</option> to
suppress this output.</para>
<table>
- <title>Manager Operational States</title>
- <tgroup cols='2'>
- <colspec colname='name' />
- <colspec colname='description' />
+ <title><command>is-system-running</command> output</title>
+ <tgroup cols='3'>
+ <colspec colname='name'/>
+ <colspec colname='description'/>
+ <colspec colname='exit-code'/>
<thead>
<row>
<entry>Name</entry>
<entry>Description</entry>
+ <entry>Exit Code</entry>
</row>
</thead>
<tbody>
@@ -1499,32 +1502,53 @@ kobject-uevent 1 systemd-udevd-kernel.socket systemd-udevd.service
<filename>basic.target</filename> is reached
or the <varname>maintenance</varname> state entered.
</para></entry>
+ <entry>&gt; 0</entry>
</row>
<row>
<entry><varname>starting</varname></entry>
<entry><para>Late bootup, before the job queue
becomes idle for the first time, or one of the
rescue targets are reached.</para></entry>
+ <entry>&gt; 0</entry>
</row>
<row>
<entry><varname>running</varname></entry>
<entry><para>The system is fully
operational.</para></entry>
+ <entry>0</entry>
</row>
<row>
<entry><varname>degraded</varname></entry>
<entry><para>The system is operational but one or more
units failed.</para></entry>
+ <entry>&gt; 0</entry>
</row>
<row>
<entry><varname>maintenance</varname></entry>
<entry><para>The rescue or emergency target is
active.</para></entry>
+ <entry>&gt; 0</entry>
</row>
<row>
<entry><varname>stopping</varname></entry>
<entry><para>The manager is shutting
down.</para></entry>
+ <entry>&gt; 0</entry>
+ </row>
+ <row>
+ <entry><varname>offline</varname></entry>
+ <entry><para>The manager is not
+ running. Specifically, this is the operational
+ state if an incompatible program is running as
+ system manager (PID 1).</para></entry>
+ <entry>&gt; 0</entry>
+ </row>
+ <row>
+ <entry><varname>unknown</varname></entry>
+ <entry><para>The operational state could not be
+ determined, due to lack of resources or another
+ error cause.</para></entry>
+ <entry>&gt; 0</entry>
</row>
</tbody>
</tgroup>
diff --git a/man/systemd-journald.service.xml b/man/systemd-journald.service.xml
index dae6ee6042..bd0082712e 100644
--- a/man/systemd-journald.service.xml
+++ b/man/systemd-journald.service.xml
@@ -99,7 +99,10 @@
reboot. To make the data persistent, it is sufficient to create
<filename>/var/log/journal/</filename> where
<filename>systemd-journald</filename> will then store the
- data.</para>
+ data:</para>
+
+ <programlisting>mkdir -p /var/log/journal
+systemd-tmpfiles --create --prefix /var/log/journal</programlisting>
<para><filename>systemd-journald</filename> will forward all
received log messages to the
diff --git a/man/systemd-machine-id-commit.service.xml b/man/systemd-machine-id-commit.service.xml
index 7c8fc0874e..10f36b3008 100644
--- a/man/systemd-machine-id-commit.service.xml
+++ b/man/systemd-machine-id-commit.service.xml
@@ -42,55 +42,50 @@
<refnamediv>
<refname>systemd-machine-id-commit.service</refname>
- <refpurpose>Commit transient machine-id to disk</refpurpose>
+ <refpurpose>Commit a transient machine-id to disk</refpurpose>
</refnamediv>
<refsynopsisdiv>
<para><filename>systemd-machine-id-commit.service</filename></para>
- <para><filename>/usr/lib/systemd/systemd-machine-id-commit</filename></para>
</refsynopsisdiv>
<refsect1>
<title>Description</title>
- <para><filename>systemd-machine-id-commit.service</filename> is a
- service responsible for committing any transient
- <filename>/etc/machine-id</filename> file to a writable file
+ <para><filename>systemd-machine-id-commit.service</filename> is an
+ early-boot service responsible for committing transient
+ <filename>/etc/machine-id</filename> files to a writable disk file
system. See
<citerefentry><refentrytitle>machine-id</refentrytitle><manvolnum>5</manvolnum></citerefentry>
- for more information about this file.</para>
-
- <para>This service is started shortly after
- <filename>local-fs.target</filename> if
- <filename>/etc/machine-id</filename> is an independent mount point
- (probably a tmpfs one) and /etc is writable.
- <command>systemd-machine-id-commit</command> will then write
- current machine ID to disk and unmount the transient
+ for more information about machine IDs.</para>
+
+ <para>This service is started after
+ <filename>local-fs.target</filename> in case
+ <filename>/etc/machine-id</filename> is a mount point of its own
+ (usually from a memory file system such as
+ <literal>tmpfs</literal>) and /etc is writable. The service will
+ invoke <command>systemd-machine-id-setup --commit</command>, which
+ writes the current transient machine ID to disk and unmount the
<filename>/etc/machine-id</filename> file in a race-free manner to
- ensure that file is always valid for other processes.</para>
-
- <para>Note that the traditional way to initialize the machine ID
- in <filename>/etc/machine-id</filename> is to use
- <command>systemd-machine-id-setup</command> by system installer
- tools. You can also use
- <citerefentry><refentrytitle>systemd-firstboot</refentrytitle><manvolnum>1</manvolnum></citerefentry>
- to initialize the machine ID on mounted (but not booted) system
- images. The main use case for that service is
- <filename>/etc/machine-id</filename> being an empty file at boot
- and initrd chaining to systemd giving it a read only file system
- that will be turned read-write later during the boot
- process.</para>
-
- <para>There is no consequence if that service fails other than a
- newer machine-id will be generated during next system boot.
- </para>
+ ensure that file is always valid and accessible for other
+ processes. See
+ <citerefentry><refentrytitle>systemd-machine-id-setup</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+ for details.</para>
+
+ <para>The main use case of this service are systems where
+ <filename>/etc/machine-id</filename> is read-only and initially
+ not initialized. In this case the system manager will generate a
+ transient machine ID file on a memory file system, and mount it
+ over <filename>/etc/machine-id</filename>, during the early boot
+ phase. This service is then invoked in a later boot phase, as soon
+ as <filename>/etc</filename> has been remounted writable and the
+ ID may thus be committed to disk to make it permanent.</para>
</refsect1>
<refsect1>
<title>See Also</title>
<para>
<citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
- <citerefentry><refentrytitle>systemd-machine-id-commit</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
<citerefentry><refentrytitle>systemd-machine-id-setup</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
<citerefentry><refentrytitle>machine-id</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
<citerefentry><refentrytitle>systemd-firstboot</refentrytitle><manvolnum>1</manvolnum></citerefentry>
diff --git a/man/systemd-machine-id-commit.xml b/man/systemd-machine-id-commit.xml
deleted file mode 100644
index d216aa0745..0000000000
--- a/man/systemd-machine-id-commit.xml
+++ /dev/null
@@ -1,123 +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 Didier Roche
-
- 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-machine-id-commit"
- xmlns:xi="http://www.w3.org/2001/XInclude">
-
- <refentryinfo>
- <title>systemd-machine-id-commit</title>
- <productname>systemd</productname>
-
- <authorgroup>
- <author>
- <contrib>Developer</contrib>
- <firstname>Didier</firstname>
- <surname>Roche</surname>
- <email>didrocks@ubuntu.com</email>
- </author>
- </authorgroup>
- </refentryinfo>
-
- <refmeta>
- <refentrytitle>systemd-machine-id-commit</refentrytitle>
- <manvolnum>1</manvolnum>
- </refmeta>
-
- <refnamediv>
- <refname>systemd-machine-id-commit</refname>
- <refpurpose>Commit transient machine ID to /etc/machine-id</refpurpose>
- </refnamediv>
-
- <refsynopsisdiv>
- <cmdsynopsis>
- <command>systemd-machine-id-commit</command>
- </cmdsynopsis>
- </refsynopsisdiv>
-
- <refsect1>
- <title>Description</title>
-
- <para><command>systemd-machine-id-commit</command> may be used to
- write on disk any transient machine ID mounted as a temporary file
- system in <filename>/etc/machine-id</filename> at boot time. See
- <citerefentry><refentrytitle>machine-id</refentrytitle><manvolnum>5</manvolnum></citerefentry>
- for more information about this file.</para>
-
- <para>This tool will execute no operation if
- <filename>/etc/machine-id</filename> doesn't contain any valid
- machine ID, isn't mounted as an independent temporary file system,
- or <filename>/etc</filename> is read-only. If those conditions are
- met, it will then write current machine ID to disk and unmount the
- transient <filename>/etc/machine-id</filename> file in a race-free
- manner to ensure that this file is always valid for other
- processes.</para>
-
- <para>Note that the traditional way to initialize the machine ID
- in <filename>/etc/machine-id</filename> is to use
- <command>systemd-machine-id-setup</command> by system installer
- tools. You can also use
- <citerefentry><refentrytitle>systemd-firstboot</refentrytitle><manvolnum>1</manvolnum></citerefentry>
- to initialize the machine ID on mounted (but not booted) system
- images.</para>
- </refsect1>
-
- <refsect1>
- <title>Options</title>
-
- <para>The following options are understood:</para>
-
- <variablelist>
- <varlistentry>
- <term><option>--root=<replaceable>root</replaceable></option></term>
- <listitem><para>Takes a directory path
- as an argument. All paths will be
- prefixed with the given alternate
- <replaceable>root</replaceable> path,
- including config search paths.
- </para></listitem>
- </varlistentry>
- <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>See Also</title>
- <para>
- <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
- <citerefentry><refentrytitle>systemd-machine-id-commit.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
- <citerefentry><refentrytitle>systemd-machine-id-setup</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
- <citerefentry><refentrytitle>machine-id</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
- <citerefentry><refentrytitle>systemd-firstboot</refentrytitle><manvolnum>1</manvolnum></citerefentry>
- </para>
- </refsect1>
-
-</refentry>
diff --git a/man/systemd-machine-id-setup.xml b/man/systemd-machine-id-setup.xml
index 182717f524..efcf408332 100644
--- a/man/systemd-machine-id-setup.xml
+++ b/man/systemd-machine-id-setup.xml
@@ -1,4 +1,4 @@
-<?xml version='1.0'?> <!--*-nxml-*-->
+<?xml version='1.0'?> <!--*- Mode: nxml; nxml-child-indent: 2; indent-tabs-mode: nil -*-->
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
@@ -35,6 +35,12 @@
<surname>Poettering</surname>
<email>lennart@poettering.net</email>
</author>
+ <author>
+ <contrib>Developer</contrib>
+ <firstname>Didier</firstname>
+ <surname>Roche</surname>
+ <email>didrocks@ubuntu.com</email>
+ </author>
</authorgroup>
</refentryinfo>
@@ -59,30 +65,43 @@
<para><command>systemd-machine-id-setup</command> may be used by
system installer tools to initialize the machine ID stored in
- <filename>/etc/machine-id</filename> at install time with a
- randomly generated ID. See
+ <filename>/etc/machine-id</filename> at install time, with a
+ provisioned or randomly generated ID. See
<citerefentry><refentrytitle>machine-id</refentrytitle><manvolnum>5</manvolnum></citerefentry>
for more information about this file.</para>
- <para>This tool will execute no operation if
- <filename>/etc/machine-id</filename> is already
- initialized.</para>
-
- <para>If a valid D-Bus machine ID is already configured for the
- system, the D-Bus machine ID is copied and used to initialize the
- machine ID in <filename>/etc/machine-id</filename>.</para>
-
- <para>If run inside a KVM virtual machine and a UUID is passed via
- the <option>-uuid</option> option, this UUID is used to initialize
- the machine ID instead of a randomly generated one. The caller
- must ensure that the UUID passed is sufficiently unique and is
- different for every booted instanced of the VM.</para>
-
- <para>Similar, if run inside a Linux container environment and a
- UUID is set for the container this is used to initialize the
- machine ID. For details see the documentation of the <ulink
- url="http://www.freedesktop.org/wiki/Software/systemd/ContainerInterface">Container
- Interface</ulink>.</para>
+ <para>If the tool is invoked without the <option>--commit</option>
+ switch <filename>/etc/machine-id</filename> is initialized with a
+ valid, new machined ID if it is missing or empty. The new machine
+ ID will be acquired in the following fashion:</para>
+
+ <orderedlist>
+ <listitem><para>If a valid D-Bus machine ID is already
+ configured for the system, the D-Bus machine ID is copied and
+ used to initialize the machine ID in
+ <filename>/etc/machine-id</filename>.</para></listitem>
+
+ <listitem><para>If run inside a KVM virtual machine and a UUID
+ is was configured (via the <option>-uuid</option>
+ option), this UUID is used to initialize the machine ID. The
+ caller must ensure that the UUID passed is sufficiently unique
+ and is different for every booted instance of the
+ VM.</para></listitem>
+
+ <listitem><para>Similar, if run inside a Linux container
+ environment and a UUID is configured for the container this is
+ used to initialize the machine ID. For details see the
+ documentation of the <ulink
+ url="http://www.freedesktop.org/wiki/Software/systemd/ContainerInterface">Container
+ Interface</ulink>.</para></listitem>
+
+ <listitem><para>Otherwise a new ID is randomly
+ generated.</para></listitem>
+ </orderedlist>
+
+ <para>The <option>--commit</option> switch may be used to commit a
+ transient machined ID to disk, making it persistent. For details,
+ see below.</para>
<para>Use
<citerefentry><refentrytitle>systemd-firstboot</refentrytitle><manvolnum>1</manvolnum></citerefentry>
@@ -97,13 +116,41 @@
<para>The following options are understood:</para>
<variablelist>
+
<varlistentry>
<term><option>--root=<replaceable>root</replaceable></option></term>
- <listitem><para>Takes a directory path as an argument. All
- paths will be prefixed with the given alternate
- <replaceable>root</replaceable> path, including config search
- paths. </para></listitem>
+ <listitem><para>Takes a directory path as argument. All paths
+ operated will be prefixed with the given alternate
+ <replaceable>root</replaceable> path, including the path for
+ <filename>/etc/machine-id</filename> itself.</para></listitem>
</varlistentry>
+
+ <varlistentry>
+ <term><option>--commit</option></term>
+ <listitem><para>Commit a transient machine ID to disk. This
+ command may be used to convert a transient machine ID into a
+ persistent one. A transient machine ID file is one that was
+ bind mounted from a memory file system (usually
+ <literal>tmpfs</literal>) to
+ <filename>/etc/machine-id</filename> during the early phase of
+ the boot process. This may happen because
+ <filename>/etc</filename> is initially read-only and was
+ missing a valid machine ID file at that point.</para>
+
+ <para>This command will execute no operation if
+ <filename>/etc/machine-id</filename> is not mounted from a
+ memory file system, or if <filename>/etc</filename> is
+ read-only. The command will write the current transient
+ machine ID to disk and unmount the
+ <filename>/etc/machine-id</filename> mount point in a
+ race-free manner to ensure that this file is always valid and
+ accessible for other processes.</para>
+
+ <para>This command is primarily used by the
+ <citerefentry><refentrytitle>systemd-machine-id-commit.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+ early-boot service.</para></listitem>
+ </varlistentry>
+
<xi:include href="standard-options.xml" xpointer="help" />
<xi:include href="standard-options.xml" xpointer="version" />
</variablelist>
@@ -122,6 +169,7 @@
<para>
<citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
<citerefentry><refentrytitle>machine-id</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+ <citerefentry><refentrytitle>systemd-machine-id-commit.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
<citerefentry project='dbus'><refentrytitle>dbus-uuidgen</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
<citerefentry><refentrytitle>systemd-firstboot</refentrytitle><manvolnum>1</manvolnum></citerefentry>
</para>
diff --git a/man/systemd-notify.xml b/man/systemd-notify.xml
index 06d5ae5319..71d501f435 100644
--- a/man/systemd-notify.xml
+++ b/man/systemd-notify.xml
@@ -124,7 +124,12 @@
systemd, non-zero otherwise. If this option is passed, no
message is sent. This option is hence unrelated to the other
options. For details about the semantics of this option, see
- <citerefentry><refentrytitle>sd_booted</refentrytitle><manvolnum>3</manvolnum></citerefentry>.</para></listitem>
+ <citerefentry><refentrytitle>sd_booted</refentrytitle><manvolnum>3</manvolnum></citerefentry>. An
+ alternative way to check for this state is to call
+ <citerefentry><refentrytitle>systemctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+ with the <command>is-system-running</command> command. It will
+ return <literal>offline</literal> if the system was not booted
+ with systemd. </para></listitem>
</varlistentry>
<xi:include href="standard-options.xml" xpointer="help" />
@@ -156,12 +161,12 @@ mkfifo /tmp/waldo
systemd-notify --ready --status="Waiting for data..."
while : ; do
- read a &lt; /tmp/waldo
- systemd-notify --status="Processing $a"
+ read a &lt; /tmp/waldo
+ systemd-notify --status="Processing $a"
- # Do something with $a ...
+ # Do something with $a ...
- systemd-notify --status="Waiting for data..."
+ systemd-notify --status="Waiting for data..."
done</programlisting>
</example>
</refsect1>
diff --git a/man/systemd-system.conf.xml b/man/systemd-system.conf.xml
index a4ba0959ea..56db9ff17e 100644
--- a/man/systemd-system.conf.xml
+++ b/man/systemd-system.conf.xml
@@ -90,9 +90,10 @@
<term><varname>LogColor=</varname></term>
<term><varname>LogLocation=</varname></term>
<term><varname>DumpCore=yes</varname></term>
+ <term><varname>CrashChangeVT=no</varname></term>
<term><varname>CrashShell=no</varname></term>
+ <term><varname>CrashReboot=no</varname></term>
<term><varname>ShowStatus=yes</varname></term>
- <term><varname>CrashChVT=1</varname></term>
<term><varname>DefaultStandardOutput=journal</varname></term>
<term><varname>DefaultStandardError=inherit</varname></term>
diff --git a/man/systemd.exec.xml b/man/systemd.exec.xml
index 7633948645..d3f56fee40 100644
--- a/man/systemd.exec.xml
+++ b/man/systemd.exec.xml
@@ -84,22 +84,27 @@
<varlistentry>
<term><varname>WorkingDirectory=</varname></term>
- <listitem><para>Takes an absolute directory path. Sets the
- working directory for executed processes. If not set, defaults
- to the root directory when systemd is running as a system
- instance and the respective user's home directory if run as
- user.</para></listitem>
+ <listitem><para>Takes an absolute directory path, or the
+ special value <literal>~</literal>. Sets the working directory
+ for executed processes. If set to <literal>~</literal> the
+ home directory of the user specified in
+ <varname>User=</varname> is used. If not set, defaults to the
+ root directory when systemd is running as a system instance
+ and the respective user's home directory if run as user. If
+ the setting is prefixed with the <literal>-</literal>
+ character, a missing working directory is not considered
+ fatal.</para></listitem>
</varlistentry>
<varlistentry>
<term><varname>RootDirectory=</varname></term>
<listitem><para>Takes an absolute directory path. Sets the
- root directory for executed processes, with the
- <citerefentry project='man-pages'><refentrytitle>chroot</refentrytitle><manvolnum>2</manvolnum></citerefentry>
+ root directory for executed processes, with the <citerefentry
+ project='man-pages'><refentrytitle>chroot</refentrytitle><manvolnum>2</manvolnum></citerefentry>
system call. If this is used, it must be ensured that the
- process and all its auxiliary files are available in the
- <function>chroot()</function> jail.</para></listitem>
+ process binary and all its auxiliary files are available in
+ the <function>chroot()</function> jail.</para></listitem>
</varlistentry>
<varlistentry>
diff --git a/man/systemd.xml b/man/systemd.xml
index 479f55de76..9e927c3204 100644
--- a/man/systemd.xml
+++ b/man/systemd.xml
@@ -1,4 +1,4 @@
-<?xml version='1.0'?> <!--*-nxml-*-->
+<?xml version='1.0'?> <!--*- Mode: nxml; nxml-child-indent: 2; indent-tabs-mode: nil -*-->
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
@@ -131,17 +131,48 @@
<varlistentry>
<term><option>--dump-core</option></term>
- <listitem><para>Dump core on crash. This switch has no effect
- when run as user instance.</para></listitem>
+ <listitem><para>Enable core dumping on crash. This switch has
+ no effect when running as user instance. This setting may also
+ be enabled during boot on the kernel command line via the
+ <varname>systemd.dump_core=</varname> option, see
+ below.</para></listitem>
</varlistentry>
+
+ <varlistentry>
+ <term><option>--crash-vt=</option><replaceable>VT</replaceable></term>
+
+ <listitem><para>Switch to a specific virtual console (VT) on
+ crash. Takes a positive integer in the range 1..63, or a
+ boolean argument. If an integer is passed, selects which VT to
+ switch to. If <constant>yes</constant>, the VT kernel messages
+ are written to is selected. If <constant>no</constant>, no VT
+ switch is attempted. This switch has no effect when running as
+ user instance. This setting may also be enabled during boot,
+ on the kernel command line via the
+ <varname>systemd.crash_vt=</varname> option, see
+ below.</para></listitem>
+ </varlistentry>
+
<varlistentry>
<term><option>--crash-shell</option></term>
- <listitem><para>Run shell on
- crash. This switch has no effect when
- run as user
- instance.</para></listitem>
+ <listitem><para>Run a shell on crash. This switch has no
+ effect when running as user instance. This setting may also be
+ enabled during boot, on the kernel command line via the
+ <varname>systemd.crash_shell=</varname> option, see
+ below.</para></listitem>
</varlistentry>
+
+ <varlistentry>
+ <term><option>--crash-reboot</option></term>
+
+ <listitem><para>Automatically reboot the system on crash. This
+ switch has no effect when running as user instance. This
+ setting may also be enabled during boot, on the kernel command
+ line via the <varname>systemd.crash_reboot=</varname> option,
+ see below.</para></listitem>
+ </varlistentry>
+
<varlistentry>
<term><option>--confirm-spawn</option></term>
@@ -854,50 +885,67 @@
<term><varname>systemd.dump_core=</varname></term>
<listitem><para>Takes a boolean argument. If
- <option>true</option>, systemd dumps core when it crashes.
- Otherwise, no core dump is created. Defaults to
- <option>true</option>.</para></listitem>
+ <option>yes</option>, the systemd manager (PID 1) dumps core
+ when it crashes. Otherwise, no core dump is created. Defaults
+ to <option>yes</option>.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><varname>systemd.crash_chvt=</varname></term>
+
+ <listitem><para>Takes a positive integer, or a boolean
+ argument. If a positive integer (in the range 1..63) is
+ specified the system manager (PID 1) will activate the specified
+ virtual terminal (VT) when it crashes. Defaults to
+ <constant>no</constant>, meaning that no such switch is
+ attempted. If set to <constant>yes</constant> the VT the
+ kernel messages are written to is selected.</para></listitem>
</varlistentry>
<varlistentry>
<term><varname>systemd.crash_shell=</varname></term>
<listitem><para>Takes a boolean argument. If
- <option>true</option>, systemd spawns a shell when it crashes.
- Otherwise, no shell is spawned. Defaults to
- <option>false</option>, for security reasons, as the shell is
- not protected by any password
+ <option>yes</option>, the system manager (PID 1) spawns a
+ shell when it crashes, after a 10s delay. Otherwise, no shell
+ is spawned. Defaults to <option>no</option>, for security
+ reasons, as the shell is not protected by password
authentication.</para></listitem>
</varlistentry>
<varlistentry>
- <term><varname>systemd.crash_chvt=</varname></term>
+ <term><varname>systemd.crash_reboot=</varname></term>
- <listitem><para>Takes an integer argument. If positive systemd
- activates the specified virtual terminal when it crashes.
- Defaults to <constant>-1</constant>.</para></listitem>
+ <listitem><para>Takes a boolean argument. If
+ <option>yes</option>, the system manager (PID 1) will reboot
+ the machine automatically when it crashes, after a 10s delay.
+ Otherwise, the system will hang indefinitely. Defaults to
+ <option>no</option>, in order to avoid a reboot loop. If
+ combined with <varname>systemd.crash_shell=</varname>, it is
+ first attempted to invoke a shell, and if this is not
+ successful the system is rebooted.</para></listitem>
</varlistentry>
<varlistentry>
<term><varname>systemd.confirm_spawn=</varname></term>
<listitem><para>Takes a boolean argument. If
- <option>true</option>, asks for confirmation when spawning
- processes. Defaults to
- <option>false</option>.</para></listitem>
+ <option>yes</option>, the system manager (PID 1) asks for
+ confirmation when spawning processes. Defaults to
+ <option>no</option>.</para></listitem>
</varlistentry>
<varlistentry>
<term><varname>systemd.show_status=</varname></term>
<listitem><para>Takes a boolean argument or the constant
- <constant>auto</constant>. If <option>true</option>, shows
- terse service status updates on the console during bootup.
- <constant>auto</constant> behaves like <option>false</option>
- until a service fails or there is a significant delay in boot.
- Defaults to <option>true</option>, unless
- <option>quiet</option> is passed as kernel command line option
- in which case it defaults to
+ <constant>auto</constant>. If <option>yes</option>, the
+ systemd manager (PID 1) shows terse service status updates on
+ the console during bootup. <constant>auto</constant> behaves
+ like <option>false</option> until a service fails or there is
+ a significant delay in boot. Defaults to
+ <option>yes</option>, unless <option>quiet</option> is passed
+ as kernel command line option in which case it defaults to
<constant>auto</constant>.</para></listitem>
</varlistentry>
diff --git a/src/activate/activate.c b/src/activate/activate.c
index 5318829442..2dfc4a0bc4 100644
--- a/src/activate/activate.c
+++ b/src/activate/activate.c
@@ -19,21 +19,20 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-#include <unistd.h>
+#include <getopt.h>
#include <sys/epoll.h>
#include <sys/prctl.h>
#include <sys/socket.h>
#include <sys/wait.h>
-#include <getopt.h>
+#include <unistd.h>
#include "systemd/sd-daemon.h"
-#include "socket-util.h"
-#include "build.h"
#include "log.h"
-#include "strv.h"
#include "macro.h"
#include "signal-util.h"
+#include "socket-util.h"
+#include "strv.h"
static char** arg_listen = NULL;
static bool arg_accept = false;
@@ -314,9 +313,7 @@ static int parse_argv(int argc, char *argv[]) {
return 0;
case ARG_VERSION:
- puts(PACKAGE_STRING);
- puts(SYSTEMD_FEATURES);
- return 0 /* done */;
+ return version();
case 'l': {
int r = strv_extend(&arg_listen, optarg);
diff --git a/src/analyze/analyze.c b/src/analyze/analyze.c
index 3657ef50f1..7054deeae5 100644
--- a/src/analyze/analyze.c
+++ b/src/analyze/analyze.c
@@ -20,25 +20,25 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-#include <stdio.h>
-#include <stdlib.h>
#include <getopt.h>
#include <locale.h>
+#include <stdio.h>
+#include <stdlib.h>
#include "sd-bus.h"
-#include "bus-util.h"
+
+#include "analyze-verify.h"
#include "bus-error.h"
-#include "log.h"
-#include "build.h"
-#include "util.h"
-#include "strxcpyx.h"
-#include "strv.h"
-#include "unit-name.h"
-#include "special.h"
+#include "bus-util.h"
#include "hashmap.h"
+#include "log.h"
#include "pager.h"
-#include "analyze-verify.h"
+#include "special.h"
+#include "strv.h"
+#include "strxcpyx.h"
#include "terminal-util.h"
+#include "unit-name.h"
+#include "util.h"
#define SCALE_X (0.1 / 1000.0) /* pixels per us */
#define SCALE_Y (20.0)
@@ -1339,9 +1339,7 @@ static int parse_argv(int argc, char *argv[]) {
return 0;
case ARG_VERSION:
- puts(PACKAGE_STRING);
- puts(SYSTEMD_FEATURES);
- return 0;
+ return version();
case ARG_USER:
arg_user = true;
@@ -1434,7 +1432,7 @@ int main(int argc, char *argv[]) {
else {
_cleanup_bus_flush_close_unref_ sd_bus *bus = NULL;
- r = bus_open_transport_systemd(arg_transport, arg_host, arg_user, &bus);
+ r = bus_connect_transport_systemd(arg_transport, arg_host, arg_user, &bus);
if (r < 0) {
log_error_errno(r, "Failed to create bus connection: %m");
goto finish;
diff --git a/src/basic/prioq.c b/src/basic/prioq.c
index b89888be0e..d55b348c22 100644
--- a/src/basic/prioq.c
+++ b/src/basic/prioq.c
@@ -19,6 +19,16 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
+/*
+ * Priority Queue
+ * The prioq object implements a priority queue. That is, it orders objects by
+ * their priority and allows O(1) access to the object with the highest
+ * priority. Insertion and removal are Θ(log n). Optionally, the caller can
+ * provide a pointer to an index which will be kept up-to-date by the prioq.
+ *
+ * The underlying algorithm used in this implementation is a Heap.
+ */
+
#include "util.h"
#include "prioq.h"
@@ -101,7 +111,7 @@ static unsigned shuffle_up(Prioq *q, unsigned idx) {
k = (idx-1)/2;
- if (q->compare_func(q->items[k].data, q->items[idx].data) < 0)
+ if (q->compare_func(q->items[k].data, q->items[idx].data) <= 0)
break;
swap(q, idx, k);
diff --git a/src/basic/selinux-util.c b/src/basic/selinux-util.c
index a39a0f775a..747e6f4dbb 100644
--- a/src/basic/selinux-util.c
+++ b/src/basic/selinux-util.c
@@ -295,14 +295,20 @@ int mac_selinux_get_child_mls_label(int socket_fd, const char *exe, const char *
return r;
}
-void mac_selinux_free(char *label) {
+char* mac_selinux_free(char *label) {
#ifdef HAVE_SELINUX
+ if (!label)
+ return NULL;
+
if (!mac_selinux_use())
- return;
+ return NULL;
+
freecon((security_context_t) label);
#endif
+
+ return NULL;
}
int mac_selinux_create_file_prepare(const char *path, mode_t mode) {
diff --git a/src/basic/selinux-util.h b/src/basic/selinux-util.h
index 8467185291..2afcaec183 100644
--- a/src/basic/selinux-util.h
+++ b/src/basic/selinux-util.h
@@ -24,6 +24,8 @@
#include <sys/socket.h>
#include <stdbool.h>
+#include "macro.h"
+
bool mac_selinux_use(void);
void mac_selinux_retest(void);
@@ -36,7 +38,7 @@ int mac_selinux_apply(const char *path, const char *label);
int mac_selinux_get_create_label_from_exe(const char *exe, char **label);
int mac_selinux_get_our_label(char **label);
int mac_selinux_get_child_mls_label(int socket_fd, const char *exe, const char *exec_label, char **label);
-void mac_selinux_free(char *label);
+char* mac_selinux_free(char *label);
int mac_selinux_create_file_prepare(const char *path, mode_t mode);
void mac_selinux_create_file_clear(void);
@@ -45,3 +47,5 @@ int mac_selinux_create_socket_prepare(const char *label);
void mac_selinux_create_socket_clear(void);
int mac_selinux_bind(int fd, const struct sockaddr *addr, socklen_t addrlen);
+
+DEFINE_TRIVIAL_CLEANUP_FUNC(char*, mac_selinux_free);
diff --git a/src/basic/strv.c b/src/basic/strv.c
index b9aef64b15..9524e80a6f 100644
--- a/src/basic/strv.c
+++ b/src/basic/strv.c
@@ -720,3 +720,28 @@ bool strv_fnmatch(char* const* patterns, const char *s, int flags) {
return false;
}
+
+char ***strv_free_free(char ***l) {
+ char ***i;
+
+ if (!l)
+ return NULL;
+
+ for (i = l; *i; i++)
+ strv_free(*i);
+
+ free(l);
+ return NULL;
+}
+
+char **strv_skip(char **l, size_t n) {
+
+ while (n > 0) {
+ if (strv_isempty(l))
+ return l;
+
+ l++, n--;
+ }
+
+ return l;
+}
diff --git a/src/basic/strv.h b/src/basic/strv.h
index f07da8cdf3..4c4b6526de 100644
--- a/src/basic/strv.h
+++ b/src/basic/strv.h
@@ -154,3 +154,7 @@ static inline bool strv_fnmatch_or_empty(char* const* patterns, const char *s, i
return strv_isempty(patterns) ||
strv_fnmatch(patterns, s, flags);
}
+
+char ***strv_free_free(char ***l);
+
+char **strv_skip(char **l, size_t n);
diff --git a/src/basic/terminal-util.c b/src/basic/terminal-util.c
index dd3d525854..287e0dfa13 100644
--- a/src/basic/terminal-util.c
+++ b/src/basic/terminal-util.c
@@ -48,7 +48,7 @@ int chvt(int vt) {
if (fd < 0)
return -errno;
- if (vt < 0) {
+ if (vt <= 0) {
int tiocl[2] = {
TIOCL_GETKMSGREDIRECT,
0
diff --git a/src/basic/util.c b/src/basic/util.c
index bc61ec0115..2bad33be1b 100644
--- a/src/basic/util.c
+++ b/src/basic/util.c
@@ -72,6 +72,7 @@
* otherwise conflicts with sys/mount.h. Yay, Linux is great! */
#include <linux/fs.h>
+#include "build.h"
#include "def.h"
#include "device-nodes.h"
#include "env-util.h"
@@ -6201,15 +6202,6 @@ int ptsname_malloc(int fd, char **ret) {
int openpt_in_namespace(pid_t pid, int flags) {
_cleanup_close_ int pidnsfd = -1, mntnsfd = -1, usernsfd = -1, rootfd = -1;
_cleanup_close_pair_ int pair[2] = { -1, -1 };
- union {
- struct cmsghdr cmsghdr;
- uint8_t buf[CMSG_SPACE(sizeof(int))];
- } control = {};
- struct msghdr mh = {
- .msg_control = &control,
- .msg_controllen = sizeof(control),
- };
- struct cmsghdr *cmsg;
siginfo_t si;
pid_t child;
int r;
@@ -6243,15 +6235,7 @@ int openpt_in_namespace(pid_t pid, int flags) {
if (unlockpt(master) < 0)
_exit(EXIT_FAILURE);
- cmsg = CMSG_FIRSTHDR(&mh);
- cmsg->cmsg_level = SOL_SOCKET;
- cmsg->cmsg_type = SCM_RIGHTS;
- cmsg->cmsg_len = CMSG_LEN(sizeof(int));
- memcpy(CMSG_DATA(cmsg), &master, sizeof(int));
-
- mh.msg_controllen = cmsg->cmsg_len;
-
- if (sendmsg(pair[1], &mh, MSG_NOSIGNAL) < 0)
+ if (send_one_fd(pair[1], master, 0) < 0)
_exit(EXIT_FAILURE);
_exit(EXIT_SUCCESS);
@@ -6265,26 +6249,7 @@ int openpt_in_namespace(pid_t pid, int flags) {
if (si.si_code != CLD_EXITED || si.si_status != EXIT_SUCCESS)
return -EIO;
- if (recvmsg(pair[0], &mh, MSG_NOSIGNAL|MSG_CMSG_CLOEXEC) < 0)
- return -errno;
-
- CMSG_FOREACH(cmsg, &mh)
- if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_RIGHTS) {
- int *fds;
- unsigned n_fds;
-
- fds = (int*) CMSG_DATA(cmsg);
- n_fds = (cmsg->cmsg_len - CMSG_LEN(0)) / sizeof(int);
-
- if (n_fds != 1) {
- close_many(fds, n_fds);
- return -EIO;
- }
-
- return fds[0];
- }
-
- return -EIO;
+ return receive_one_fd(pair[0], 0);
}
ssize_t fgetxattrat_fake(int dirfd, const char *filename, const char *attribute, void *value, size_t size, int flags) {
@@ -6884,7 +6849,7 @@ int fgetxattr_malloc(int fd, const char *name, char **value) {
}
}
-int send_one_fd(int transport_fd, int fd) {
+int send_one_fd(int transport_fd, int fd, int flags) {
union {
struct cmsghdr cmsghdr;
uint8_t buf[CMSG_SPACE(sizeof(int))];
@@ -6894,7 +6859,6 @@ int send_one_fd(int transport_fd, int fd) {
.msg_controllen = sizeof(control),
};
struct cmsghdr *cmsg;
- ssize_t k;
assert(transport_fd >= 0);
assert(fd >= 0);
@@ -6906,14 +6870,13 @@ int send_one_fd(int transport_fd, int fd) {
memcpy(CMSG_DATA(cmsg), &fd, sizeof(int));
mh.msg_controllen = CMSG_SPACE(sizeof(int));
- k = sendmsg(transport_fd, &mh, MSG_NOSIGNAL);
- if (k < 0)
+ if (sendmsg(transport_fd, &mh, MSG_NOSIGNAL | flags) < 0)
return -errno;
return 0;
}
-int receive_one_fd(int transport_fd) {
+int receive_one_fd(int transport_fd, int flags) {
union {
struct cmsghdr cmsghdr;
uint8_t buf[CMSG_SPACE(sizeof(int))];
@@ -6922,33 +6885,45 @@ int receive_one_fd(int transport_fd) {
.msg_control = &control,
.msg_controllen = sizeof(control),
};
- struct cmsghdr *cmsg;
- ssize_t k;
+ struct cmsghdr *cmsg, *found = NULL;
assert(transport_fd >= 0);
/*
- * Receive a single FD via @transport_fd. We don't care for the
- * transport-type, but the caller must assure that no other CMSG types
- * than SCM_RIGHTS is enabled. We also retrieve a single FD at most, so
- * for packet-based transports, the caller must ensure to send only a
- * single FD per packet.
- * This is best used in combination with send_one_fd().
+ * Receive a single FD via @transport_fd. We don't care for
+ * the transport-type. We retrieve a single FD at most, so for
+ * packet-based transports, the caller must ensure to send
+ * only a single FD per packet. This is best used in
+ * combination with send_one_fd().
*/
- k = recvmsg(transport_fd, &mh, MSG_NOSIGNAL | MSG_CMSG_CLOEXEC);
- if (k < 0)
+ if (recvmsg(transport_fd, &mh, MSG_NOSIGNAL | MSG_CMSG_CLOEXEC | flags) < 0)
return -errno;
- cmsg = CMSG_FIRSTHDR(&mh);
- if (!cmsg || CMSG_NXTHDR(&mh, cmsg) ||
- cmsg->cmsg_level != SOL_SOCKET ||
- cmsg->cmsg_type != SCM_RIGHTS ||
- cmsg->cmsg_len != CMSG_LEN(sizeof(int)) ||
- *(const int *)CMSG_DATA(cmsg) < 0) {
+ CMSG_FOREACH(cmsg, &mh) {
+ if (cmsg->cmsg_level == SOL_SOCKET &&
+ cmsg->cmsg_type == SCM_RIGHTS &&
+ cmsg->cmsg_len == CMSG_LEN(sizeof(int))) {
+ assert(!found);
+ found = cmsg;
+ break;
+ }
+ }
+
+ if (!found) {
cmsg_close_all(&mh);
return -EIO;
}
- return *(const int *)CMSG_DATA(cmsg);
+ return *(int*) CMSG_DATA(found);
+}
+
+void nop_signal_handler(int sig) {
+ /* nothing here */
+}
+
+int version(void) {
+ puts(PACKAGE_STRING "\n"
+ SYSTEMD_FEATURES);
+ return 0;
}
diff --git a/src/basic/util.h b/src/basic/util.h
index 56d9f037bf..afd906477a 100644
--- a/src/basic/util.h
+++ b/src/basic/util.h
@@ -942,5 +942,9 @@ int reset_uid_gid(void);
int getxattr_malloc(const char *path, const char *name, char **value, bool allow_symlink);
int fgetxattr_malloc(int fd, const char *name, char **value);
-int send_one_fd(int transport_fd, int fd);
-int receive_one_fd(int transport_fd);
+int send_one_fd(int transport_fd, int fd, int flags);
+int receive_one_fd(int transport_fd, int flags);
+
+void nop_signal_handler(int sig);
+
+int version(void);
diff --git a/src/binfmt/binfmt.c b/src/binfmt/binfmt.c
index 1e216f52bd..ddb5c88806 100644
--- a/src/binfmt/binfmt.c
+++ b/src/binfmt/binfmt.c
@@ -19,20 +19,19 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-#include <stdlib.h>
-#include <stdbool.h>
#include <errno.h>
-#include <string.h>
-#include <stdio.h>
-#include <limits.h>
#include <getopt.h>
+#include <limits.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "conf-files.h"
+#include "fileio.h"
#include "log.h"
#include "strv.h"
#include "util.h"
-#include "conf-files.h"
-#include "fileio.h"
-#include "build.h"
static const char conf_file_dirs[] = CONF_DIRS_NULSTR("binfmt");
@@ -143,9 +142,7 @@ static int parse_argv(int argc, char *argv[]) {
return 0;
case ARG_VERSION:
- puts(PACKAGE_STRING);
- puts(SYSTEMD_FEATURES);
- return 0;
+ return version();
case '?':
return -EINVAL;
diff --git a/src/boot/bootctl.c b/src/boot/bootctl.c
index ac1711b318..f991e30cfa 100644
--- a/src/boot/bootctl.c
+++ b/src/boot/bootctl.c
@@ -20,28 +20,27 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-#include <stdio.h>
-#include <getopt.h>
-#include <stdlib.h>
#include <assert.h>
-#include <sys/statfs.h>
-#include <sys/stat.h>
-#include <errno.h>
-#include <string.h>
-#include <unistd.h>
-#include <sys/mman.h>
-#include <dirent.h>
+#include <blkid/blkid.h>
#include <ctype.h>
-#include <limits.h>
+#include <dirent.h>
+#include <errno.h>
#include <ftw.h>
+#include <getopt.h>
+#include <limits.h>
#include <stdbool.h>
-#include <blkid/blkid.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <sys/statfs.h>
+#include <unistd.h>
+#include "blkid-util.h"
#include "efivars.h"
-#include "build.h"
-#include "util.h"
#include "rm-rf.h"
-#include "blkid-util.h"
+#include "util.h"
static int verify_esp(const char *p, uint32_t *part, uint64_t *pstart, uint64_t *psize, sd_id128_t *uuid) {
struct statfs sfs;
@@ -967,8 +966,7 @@ static int parse_argv(int argc, char *argv[]) {
return 0;
case ARG_VERSION:
- printf(VERSION "\n");
- return 0;
+ return version();
case ARG_PATH:
arg_path = optarg;
diff --git a/src/bus-proxyd/bus-proxyd.c b/src/bus-proxyd/bus-proxyd.c
index 3cc3b33ae7..2bc265d9b4 100644
--- a/src/bus-proxyd/bus-proxyd.c
+++ b/src/bus-proxyd/bus-proxyd.c
@@ -22,26 +22,26 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-#include <sys/socket.h>
-#include <unistd.h>
-#include <string.h>
#include <errno.h>
-#include <sys/prctl.h>
-#include <stddef.h>
#include <getopt.h>
#include <pthread.h>
+#include <stddef.h>
+#include <string.h>
+#include <sys/prctl.h>
+#include <sys/socket.h>
+#include <unistd.h>
-#include "log.h"
-#include "util.h"
#include "sd-daemon.h"
+
#include "bus-internal.h"
-#include "build.h"
-#include "strv.h"
-#include "def.h"
-#include "capability.h"
#include "bus-xml-policy.h"
-#include "proxy.h"
+#include "capability.h"
+#include "def.h"
#include "formats-util.h"
+#include "log.h"
+#include "proxy.h"
+#include "strv.h"
+#include "util.h"
static char *arg_address = NULL;
static char **arg_configuration = NULL;
@@ -215,9 +215,7 @@ static int parse_argv(int argc, char *argv[]) {
return 0;
case ARG_VERSION:
- puts(PACKAGE_STRING);
- puts(SYSTEMD_FEATURES);
- return 0;
+ return version();
case ARG_ADDRESS:
r = free_and_strdup(&arg_address, optarg);
diff --git a/src/bus-proxyd/stdio-bridge.c b/src/bus-proxyd/stdio-bridge.c
index f275f6705f..168fc9ead0 100644
--- a/src/bus-proxyd/stdio-bridge.c
+++ b/src/bus-proxyd/stdio-bridge.c
@@ -21,23 +21,23 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-#include <unistd.h>
-#include <string.h>
#include <errno.h>
-#include <stddef.h>
#include <getopt.h>
+#include <stddef.h>
+#include <string.h>
+#include <unistd.h>
-#include "log.h"
-#include "util.h"
#include "sd-daemon.h"
#include "sd-bus.h"
+
#include "bus-internal.h"
#include "bus-util.h"
-#include "build.h"
-#include "strv.h"
#include "def.h"
-#include "proxy.h"
#include "formats-util.h"
+#include "log.h"
+#include "proxy.h"
+#include "strv.h"
+#include "util.h"
static char *arg_address = NULL;
static char *arg_command_line_buffer = NULL;
@@ -86,9 +86,7 @@ static int parse_argv(int argc, char *argv[]) {
return 0;
case ARG_VERSION:
- puts(PACKAGE_STRING);
- puts(SYSTEMD_FEATURES);
- return 0;
+ return version();
case ARG_ADDRESS: {
char *a;
diff --git a/src/cgls/cgls.c b/src/cgls/cgls.c
index ec4215f741..41c539a1bc 100644
--- a/src/cgls/cgls.c
+++ b/src/cgls/cgls.c
@@ -19,25 +19,25 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-#include <stdio.h>
-#include <unistd.h>
#include <errno.h>
#include <getopt.h>
+#include <stdio.h>
#include <string.h>
+#include <unistd.h>
+
+#include "sd-bus.h"
+#include "bus-error.h"
+#include "bus-util.h"
#include "cgroup-show.h"
#include "cgroup-util.h"
+#include "fileio.h"
#include "log.h"
-#include "path-util.h"
-#include "util.h"
-#include "pager.h"
-#include "build.h"
#include "output-mode.h"
-#include "fileio.h"
-#include "sd-bus.h"
-#include "bus-util.h"
-#include "bus-error.h"
+#include "pager.h"
+#include "path-util.h"
#include "unit-name.h"
+#include "util.h"
static bool arg_no_pager = false;
static bool arg_kernel_threads = false;
@@ -89,9 +89,7 @@ static int parse_argv(int argc, char *argv[]) {
return 0;
case ARG_VERSION:
- puts(PACKAGE_STRING);
- puts(SYSTEMD_FEATURES);
- return 0;
+ return version();
case ARG_NO_PAGER:
arg_no_pager = true;
@@ -147,7 +145,7 @@ static int get_cgroup_root(char **ret) {
if (!path)
return log_oom();
- r = bus_open_transport(BUS_TRANSPORT_LOCAL, NULL, false, &bus);
+ r = bus_connect_transport_systemd(BUS_TRANSPORT_LOCAL, NULL, false, &bus);
if (r < 0)
return log_error_errno(r, "Failed to create bus connection: %m");
diff --git a/src/cgroups-agent/cgroups-agent.c b/src/cgroups-agent/cgroups-agent.c
index 612bc8fdec..b79519dd09 100644
--- a/src/cgroups-agent/cgroups-agent.c
+++ b/src/cgroups-agent/cgroups-agent.c
@@ -43,7 +43,7 @@ int main(int argc, char *argv[]) {
* this to avoid an activation loop when we start dbus when we
* are called when the dbus service is shut down. */
- r = bus_open_system_systemd(&bus);
+ r = bus_connect_system_systemd(&bus);
if (r < 0) {
/* If we couldn't connect we assume this was triggered
* while systemd got restarted/transitioned from
diff --git a/src/cgtop/cgtop.c b/src/cgtop/cgtop.c
index 9cf13cf57d..ad9cd2532f 100644
--- a/src/cgtop/cgtop.c
+++ b/src/cgtop/cgtop.c
@@ -19,27 +19,27 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-#include <errno.h>
-#include <string.h>
-#include <stdlib.h>
-#include <stdint.h>
-#include <unistd.h>
#include <alloca.h>
+#include <errno.h>
#include <getopt.h>
#include <signal.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
-#include "path-util.h"
-#include "terminal-util.h"
-#include "process-util.h"
-#include "util.h"
-#include "hashmap.h"
-#include "cgroup-util.h"
-#include "build.h"
-#include "fileio.h"
#include "sd-bus.h"
-#include "bus-util.h"
+
#include "bus-error.h"
+#include "bus-util.h"
+#include "cgroup-util.h"
+#include "fileio.h"
+#include "hashmap.h"
+#include "path-util.h"
+#include "process-util.h"
+#include "terminal-util.h"
#include "unit-name.h"
+#include "util.h"
typedef struct Group {
char *path;
@@ -696,9 +696,7 @@ static int parse_argv(int argc, char *argv[]) {
return 0;
case ARG_VERSION:
- puts(PACKAGE_STRING);
- puts(SYSTEMD_FEATURES);
- return 0;
+ return version();
case ARG_CPU_TYPE:
if (optarg) {
@@ -863,7 +861,7 @@ static int get_cgroup_root(char **ret) {
if (!path)
return log_oom();
- r = bus_open_transport(BUS_TRANSPORT_LOCAL, NULL, false, &bus);
+ r = bus_connect_transport_systemd(BUS_TRANSPORT_LOCAL, NULL, false, &bus);
if (r < 0)
return log_error_errno(r, "Failed to create bus connection: %m");
diff --git a/src/core/dbus-execute.c b/src/core/dbus-execute.c
index 868c8cc05a..adf613d328 100644
--- a/src/core/dbus-execute.c
+++ b/src/core/dbus-execute.c
@@ -595,6 +595,33 @@ static int property_get_address_families(
return sd_bus_message_close_container(reply);
}
+static int property_get_working_directory(
+ sd_bus *bus,
+ const char *path,
+ const char *interface,
+ const char *property,
+ sd_bus_message *reply,
+ void *userdata,
+ sd_bus_error *error) {
+
+ ExecContext *c = userdata;
+ const char *wd;
+
+ assert(bus);
+ assert(reply);
+ assert(c);
+
+ if (c->working_directory_home)
+ wd = "~";
+ else
+ wd = c->working_directory;
+
+ if (c->working_directory_missing_ok)
+ wd = strjoina("!", wd);
+
+ return sd_bus_message_append(reply, "s", wd);
+}
+
const sd_bus_vtable bus_exec_vtable[] = {
SD_BUS_VTABLE_START(0),
SD_BUS_PROPERTY("Environment", "as", NULL, offsetof(ExecContext, environment), SD_BUS_VTABLE_PROPERTY_CONST),
@@ -616,7 +643,7 @@ const sd_bus_vtable bus_exec_vtable[] = {
SD_BUS_PROPERTY("LimitNICE", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_NICE]), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("LimitRTPRIO", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_RTPRIO]), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("LimitRTTIME", "t", property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_RTTIME]), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("WorkingDirectory", "s", NULL, offsetof(ExecContext, working_directory), SD_BUS_VTABLE_PROPERTY_CONST),
+ SD_BUS_PROPERTY("WorkingDirectory", "s", property_get_working_directory, 0, SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("RootDirectory", "s", NULL, offsetof(ExecContext, root_directory), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("OOMScoreAdjust", "i", property_get_oom_score_adjust, 0, SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("Nice", "i", property_get_nice, 0, SD_BUS_VTABLE_PROPERTY_CONST),
@@ -847,8 +874,7 @@ int bus_exec_context_set_transient_property(
return 1;
- } else if (STR_IN_SET(name,
- "TTYPath", "WorkingDirectory", "RootDirectory")) {
+ } else if (STR_IN_SET(name, "TTYPath", "RootDirectory")) {
const char *s;
r = sd_bus_message_read(message, "s", &s);
@@ -859,24 +885,51 @@ int bus_exec_context_set_transient_property(
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "%s takes an absolute path", name);
if (mode != UNIT_CHECK) {
- char *t;
+ if (streq(name, "TTYPath"))
+ r = free_and_strdup(&c->tty_path, s);
+ else {
+ assert(streq(name, "RootDirectory"));
+ r = free_and_strdup(&c->root_directory, s);
+ }
+ if (r < 0)
+ return r;
- t = strdup(s);
- if (!t)
- return -ENOMEM;
+ unit_write_drop_in_private_format(u, mode, name, "%s=%s\n", name, s);
+ }
- if (streq(name, "TTYPath")) {
- free(c->tty_path);
- c->tty_path = t;
- } else if (streq(name, "WorkingDirectory")) {
- free(c->working_directory);
- c->working_directory = t;
- } else if (streq(name, "RootDirectory")) {
- free(c->root_directory);
- c->root_directory = t;
+ return 1;
+
+ } else if (streq(name, "WorkingDirectory")) {
+ const char *s;
+ bool missing_ok;
+
+ r = sd_bus_message_read(message, "s", &s);
+ if (r < 0)
+ return r;
+
+ if (s[0] == '-') {
+ missing_ok = true;
+ s++;
+ } else
+ missing_ok = false;
+
+ if (!streq(s, "~") && !path_is_absolute(s))
+ return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "WorkingDirectory= expects an absolute path or '~'");
+
+ if (mode != UNIT_CHECK) {
+ if (streq(s, "~")) {
+ c->working_directory = mfree(c->working_directory);
+ c->working_directory_home = true;
+ } else {
+ r = free_and_strdup(&c->working_directory, s);
+ if (r < 0)
+ return r;
+
+ c->working_directory_home = false;
}
- unit_write_drop_in_private_format(u, mode, name, "%s=%s\n", name, s);
+ c->working_directory_missing_ok = missing_ok;
+ unit_write_drop_in_private_format(u, mode, name, "WorkingDirectory=%s%s", missing_ok ? "-" : "", s);
}
return 1;
diff --git a/src/core/execute.c b/src/core/execute.c
index 7796c07fcf..137a176c18 100644
--- a/src/core/execute.c
+++ b/src/core/execute.c
@@ -1325,7 +1325,7 @@ static int exec_child(
_cleanup_strv_free_ char **our_env = NULL, **pam_env = NULL, **final_env = NULL, **final_argv = NULL;
_cleanup_free_ char *mac_selinux_context_net = NULL;
- const char *username = NULL, *home = NULL, *shell = NULL;
+ const char *username = NULL, *home = NULL, *shell = NULL, *wd;
unsigned n_dont_close = 0;
int dont_close[n_fds + 4];
uid_t uid = UID_INVALID;
@@ -1698,6 +1698,13 @@ static int exec_child(
}
}
+ if (context->working_directory_home)
+ wd = home;
+ else if (context->working_directory)
+ wd = context->working_directory;
+ else
+ wd = "/";
+
if (params->apply_chroot) {
if (!needs_mount_namespace && context->root_directory)
if (chroot(context->root_directory) < 0) {
@@ -1705,21 +1712,15 @@ static int exec_child(
return -errno;
}
- if (chdir(context->working_directory ?: "/") < 0 &&
+ if (chdir(wd) < 0 &&
!context->working_directory_missing_ok) {
*exit_status = EXIT_CHDIR;
return -errno;
}
} else {
- _cleanup_free_ char *d = NULL;
-
- if (asprintf(&d, "%s/%s",
- context->root_directory ?: "",
- context->working_directory ?: "") < 0) {
- *exit_status = EXIT_MEMORY;
- return -ENOMEM;
- }
+ const char *d;
+ d = strjoina(strempty(context->root_directory), "/", strempty(wd));
if (chdir(d) < 0 &&
!context->working_directory_missing_ok) {
*exit_status = EXIT_CHDIR;
diff --git a/src/core/execute.h b/src/core/execute.h
index a750246a89..2c93044748 100644
--- a/src/core/execute.h
+++ b/src/core/execute.h
@@ -103,6 +103,7 @@ struct ExecContext {
struct rlimit *rlimit[_RLIMIT_MAX];
char *working_directory, *root_directory;
bool working_directory_missing_ok;
+ bool working_directory_home;
mode_t umask;
int oom_score_adjust;
diff --git a/src/core/load-fragment-gperf.gperf.m4 b/src/core/load-fragment-gperf.gperf.m4
index fd293d8287..27159aa4c7 100644
--- a/src/core/load-fragment-gperf.gperf.m4
+++ b/src/core/load-fragment-gperf.gperf.m4
@@ -17,7 +17,7 @@ struct ConfigPerfItem;
%%
m4_dnl Define the context options only once
m4_define(`EXEC_CONTEXT_CONFIG_ITEMS',
-`$1.WorkingDirectory, config_parse_unit_path_printf, 0, offsetof($1, exec_context.working_directory)
+`$1.WorkingDirectory, config_parse_working_directory, 0, offsetof($1, exec_context)
$1.RootDirectory, config_parse_unit_path_printf, 0, offsetof($1, exec_context.root_directory)
$1.User, config_parse_unit_string_printf, 0, offsetof($1, exec_context.user)
$1.Group, config_parse_unit_string_printf, 0, offsetof($1, exec_context.group)
diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c
index a13f42b5e0..7045c31f2e 100644
--- a/src/core/load-fragment.c
+++ b/src/core/load-fragment.c
@@ -20,44 +20,42 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-#include <linux/oom.h>
#include <errno.h>
-#include <string.h>
#include <fcntl.h>
-#include <sched.h>
#include <linux/fs.h>
-#include <sys/stat.h>
+#include <linux/oom.h>
+#include <sched.h>
+#include <string.h>
#include <sys/resource.h>
-
+#include <sys/stat.h>
#ifdef HAVE_SECCOMP
#include <seccomp.h>
#endif
-#include "unit.h"
-#include "strv.h"
+#include "af-list.h"
+#include "bus-error.h"
+#include "bus-internal.h"
+#include "bus-util.h"
+#include "cap-list.h"
+#include "cgroup.h"
#include "conf-parser.h"
-#include "load-fragment.h"
-#include "log.h"
+#include "env-util.h"
+#include "errno-list.h"
#include "ioprio.h"
-#include "securebits.h"
+#include "log.h"
#include "missing.h"
-#include "unit-name.h"
-#include "unit-printf.h"
-#include "utf8.h"
#include "path-util.h"
-#include "env-util.h"
-#include "cgroup.h"
-#include "bus-util.h"
-#include "bus-error.h"
-#include "errno-list.h"
-#include "af-list.h"
-#include "cap-list.h"
-#include "signal-util.h"
-#include "bus-internal.h"
-
#ifdef HAVE_SECCOMP
#include "seccomp-util.h"
#endif
+#include "securebits.h"
+#include "signal-util.h"
+#include "strv.h"
+#include "unit-name.h"
+#include "unit-printf.h"
+#include "unit.h"
+#include "utf8.h"
+#include "load-fragment.h"
int config_parse_warn_compat(
const char *unit,
@@ -195,16 +193,17 @@ int config_parse_unit_strv_printf(const char *unit,
k ? k : rvalue, data, userdata);
}
-int config_parse_unit_path_printf(const char *unit,
- const char *filename,
- unsigned line,
- const char *section,
- unsigned section_line,
- const char *lvalue,
- int ltype,
- const char *rvalue,
- void *data,
- void *userdata) {
+int config_parse_unit_path_printf(
+ const char *unit,
+ const char *filename,
+ unsigned line,
+ const char *section,
+ unsigned section_line,
+ const char *lvalue,
+ int ltype,
+ const char *rvalue,
+ void *data,
+ void *userdata) {
_cleanup_free_ char *k = NULL;
Unit *u = userdata;
@@ -1846,6 +1845,70 @@ int config_parse_bus_endpoint_policy(
return bus_endpoint_add_policy(c->bus_endpoint, name, access);
}
+int config_parse_working_directory(
+ const char *unit,
+ const char *filename,
+ unsigned line,
+ const char *section,
+ unsigned section_line,
+ const char *lvalue,
+ int ltype,
+ const char *rvalue,
+ void *data,
+ void *userdata) {
+
+ ExecContext *c = data;
+ Unit *u = userdata;
+ bool missing_ok;
+ int r;
+
+ assert(filename);
+ assert(lvalue);
+ assert(rvalue);
+ assert(c);
+ assert(u);
+
+ if (rvalue[0] == '-') {
+ missing_ok = true;
+ rvalue++;
+ } else
+ missing_ok = false;
+
+ if (streq(rvalue, "~")) {
+ c->working_directory_home = true;
+ c->working_directory = mfree(c->working_directory);
+ } else {
+ _cleanup_free_ char *k = NULL;
+
+ r = unit_full_printf(u, rvalue, &k);
+ if (r < 0) {
+ log_syntax(unit, LOG_ERR, filename, line, r, "Failed to resolve unit specifiers in working directory path '%s', ignoring: %m", rvalue);
+ return 0;
+ }
+
+ path_kill_slashes(k);
+
+ if (!utf8_is_valid(k)) {
+ log_invalid_utf8(unit, LOG_ERR, filename, line, 0, rvalue);
+ return 0;
+ }
+
+ if (!path_is_absolute(k)) {
+ log_syntax(unit, LOG_ERR, filename, line, 0, "Working directory path '%s' is not absolute, ignoring.", rvalue);
+ return 0;
+ }
+
+ free(c->working_directory);
+ c->working_directory = k;
+ k = NULL;
+
+ c->working_directory_home = false;
+ }
+
+ c->working_directory_missing_ok = missing_ok;
+ return 0;
+}
+
int config_parse_unit_env_file(const char *unit,
const char *filename,
unsigned line,
diff --git a/src/core/load-fragment.h b/src/core/load-fragment.h
index 5d0a09249f..6ee7c71bc4 100644
--- a/src/core/load-fragment.h
+++ b/src/core/load-fragment.h
@@ -106,6 +106,7 @@ int config_parse_protect_home(const char* unit, const char *filename, unsigned l
int config_parse_protect_system(const char* unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
int config_parse_bus_name(const char* unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
int config_parse_exec_utmp_mode(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+int config_parse_working_directory(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
/* gperf prototypes */
const struct ConfigPerfItem* load_fragment_gperf_lookup(const char *key, unsigned length);
diff --git a/src/core/main.c b/src/core/main.c
index bc72a2b00b..bac2043281 100644
--- a/src/core/main.c
+++ b/src/core/main.c
@@ -19,63 +19,63 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-#include <stdio.h>
#include <errno.h>
-#include <string.h>
-#include <unistd.h>
-#include <sys/stat.h>
+#include <fcntl.h>
#include <getopt.h>
#include <signal.h>
-#include <fcntl.h>
-#include <sys/prctl.h>
+#include <stdio.h>
+#include <string.h>
#include <sys/mount.h>
-
-#ifdef HAVE_VALGRIND_VALGRIND_H
-#include <valgrind/valgrind.h>
-#endif
+#include <sys/prctl.h>
+#include <sys/reboot.h>
+#include <sys/stat.h>
+#include <unistd.h>
#ifdef HAVE_SECCOMP
#include <seccomp.h>
#endif
+#ifdef HAVE_VALGRIND_VALGRIND_H
+#include <valgrind/valgrind.h>
+#endif
#include "sd-daemon.h"
#include "sd-bus.h"
-#include "log.h"
-#include "fdset.h"
-#include "special.h"
-#include "conf-parser.h"
-#include "missing.h"
-#include "pager.h"
-#include "build.h"
-#include "strv.h"
-#include "def.h"
-#include "virt.h"
+
#include "architecture.h"
-#include "watchdog.h"
-#include "switch-root.h"
+#include "build.h"
+#include "bus-error.h"
+#include "bus-util.h"
#include "capability.h"
-#include "killall.h"
-#include "env-util.h"
#include "clock-util.h"
+#include "conf-parser.h"
+#include "dbus-manager.h"
+#include "def.h"
+#include "env-util.h"
+#include "fdset.h"
#include "fileio.h"
-#include "bus-error.h"
-#include "bus-util.h"
-#include "selinux-util.h"
#include "formats-util.h"
-#include "process-util.h"
-#include "terminal-util.h"
-#include "signal-util.h"
-#include "manager.h"
-#include "dbus-manager.h"
+#include "hostname-setup.h"
+#include "ima-setup.h"
+#include "killall.h"
+#include "kmod-setup.h"
#include "load-fragment.h"
-
-#include "mount-setup.h"
+#include "log.h"
#include "loopback-setup.h"
-#include "hostname-setup.h"
#include "machine-id-setup.h"
+#include "manager.h"
+#include "missing.h"
+#include "mount-setup.h"
+#include "pager.h"
+#include "process-util.h"
#include "selinux-setup.h"
-#include "ima-setup.h"
+#include "selinux-util.h"
+#include "signal-util.h"
#include "smack-setup.h"
-#include "kmod-setup.h"
+#include "special.h"
+#include "strv.h"
+#include "switch-root.h"
+#include "terminal-util.h"
+#include "virt.h"
+#include "watchdog.h"
static enum {
ACTION_RUN,
@@ -88,8 +88,9 @@ static enum {
static char *arg_default_unit = NULL;
static ManagerRunningAs arg_running_as = _MANAGER_RUNNING_AS_INVALID;
static bool arg_dump_core = true;
-static bool arg_crash_shell = false;
static int arg_crash_chvt = -1;
+static bool arg_crash_shell = false;
+static bool arg_crash_reboot = false;
static bool arg_confirm_spawn = false;
static ShowStatus arg_show_status = _SHOW_STATUS_UNSET;
static bool arg_switched_root = false;
@@ -116,8 +117,6 @@ static bool arg_default_blockio_accounting = false;
static bool arg_default_memory_accounting = false;
static bool arg_default_tasks_accounting = false;
-static void nop_handler(int sig) {}
-
static void pager_open_if_enabled(void) {
if (arg_no_pager <= 0)
@@ -126,49 +125,65 @@ static void pager_open_if_enabled(void) {
pager_open(false);
}
+noreturn static void freeze_or_reboot(void) {
+
+ if (arg_crash_reboot) {
+ log_notice("Rebooting in 10s...");
+ (void) sleep(10);
+
+ log_notice("Rebooting now...");
+ (void) reboot(RB_AUTOBOOT);
+ log_emergency_errno(errno, "Failed to reboot: %m");
+ }
+
+ log_emergency("Freezing execution.");
+ freeze();
+}
+
noreturn static void crash(int sig) {
if (getpid() != 1)
/* Pass this on immediately, if this is not PID 1 */
- raise(sig);
+ (void) raise(sig);
else if (!arg_dump_core)
log_emergency("Caught <%s>, not dumping core.", signal_to_string(sig));
else {
struct sigaction sa = {
- .sa_handler = nop_handler,
+ .sa_handler = nop_signal_handler,
.sa_flags = SA_NOCLDSTOP|SA_RESTART,
};
pid_t pid;
/* We want to wait for the core process, hence let's enable SIGCHLD */
- sigaction(SIGCHLD, &sa, NULL);
+ (void) sigaction(SIGCHLD, &sa, NULL);
pid = raw_clone(SIGCHLD, NULL);
if (pid < 0)
log_emergency_errno(errno, "Caught <%s>, cannot fork for core dump: %m", signal_to_string(sig));
-
else if (pid == 0) {
- struct rlimit rl = {};
+ struct rlimit rl = {
+ .rlim_cur = RLIM_INFINITY,
+ .rlim_max = RLIM_INFINITY,
+ };
/* Enable default signal handler for core dump */
- zero(sa);
- sa.sa_handler = SIG_DFL;
- sigaction(sig, &sa, NULL);
+ sa = (struct sigaction) {
+ .sa_handler = SIG_DFL,
+ };
+ (void) sigaction(sig, &sa, NULL);
/* Don't limit the core dump size */
- rl.rlim_cur = RLIM_INFINITY;
- rl.rlim_max = RLIM_INFINITY;
- setrlimit(RLIMIT_CORE, &rl);
+ (void) setrlimit(RLIMIT_CORE, &rl);
/* Just to be sure... */
(void) chdir("/");
/* Raise the signal again */
pid = raw_getpid();
- kill(pid, sig); /* raise() would kill the parent */
+ (void) kill(pid, sig); /* raise() would kill the parent */
assert_not_reached("We shouldn't be here...");
- _exit(1);
+ _exit(EXIT_FAILURE);
} else {
siginfo_t status;
int r;
@@ -190,8 +205,8 @@ noreturn static void crash(int sig) {
}
}
- if (arg_crash_chvt)
- chvt(arg_crash_chvt);
+ if (arg_crash_chvt >= 0)
+ (void) chvt(arg_crash_chvt);
if (arg_crash_shell) {
struct sigaction sa = {
@@ -200,27 +215,30 @@ noreturn static void crash(int sig) {
};
pid_t pid;
- log_info("Executing crash shell in 10s...");
- sleep(10);
+ log_notice("Executing crash shell in 10s...");
+ (void) sleep(10);
/* Let the kernel reap children for us */
- assert_se(sigaction(SIGCHLD, &sa, NULL) == 0);
+ (void) sigaction(SIGCHLD, &sa, NULL);
pid = raw_clone(SIGCHLD, NULL);
if (pid < 0)
log_emergency_errno(errno, "Failed to fork off crash shell: %m");
else if (pid == 0) {
- make_console_stdio();
- execle("/bin/sh", "/bin/sh", NULL, environ);
+ (void) setsid();
+ (void) make_console_stdio();
+ (void) execle("/bin/sh", "/bin/sh", NULL, environ);
log_emergency_errno(errno, "execle() failed: %m");
- _exit(1);
- } else
- log_info("Successfully spawned crash shell as PID "PID_FMT".", pid);
+ freeze_or_reboot();
+ _exit(EXIT_FAILURE);
+ } else {
+ log_info("Spawned crash shell as PID "PID_FMT".", pid);
+ freeze();
+ }
}
- log_emergency("Freezing execution.");
- freeze();
+ freeze_or_reboot();
}
static void install_crash_handler(void) {
@@ -254,17 +272,20 @@ static int console_setup(void) {
return 0;
}
-static int set_default_unit(const char *u) {
- char *c;
+static int parse_crash_chvt(const char *value) {
+ int b;
- assert(u);
+ if (safe_atoi(value, &arg_crash_chvt) >= 0)
+ return 0;
- c = strdup(u);
- if (!c)
- return -ENOMEM;
+ b = parse_boolean(value);
+ if (b < 0)
+ return b;
- free(arg_default_unit);
- arg_default_unit = c;
+ if (b > 0)
+ arg_crash_chvt = 0; /* switch to where kmsg goes */
+ else
+ arg_crash_chvt = -1; /* turn off switching */
return 0;
}
@@ -292,12 +313,12 @@ static int parse_proc_cmdline_item(const char *key, const char *value) {
if (streq(key, "systemd.unit") && value) {
if (!in_initrd())
- return set_default_unit(value);
+ return free_and_strdup(&arg_default_unit, value);
} else if (streq(key, "rd.systemd.unit") && value) {
if (in_initrd())
- return set_default_unit(value);
+ return free_and_strdup(&arg_default_unit, value);
} else if (streq(key, "systemd.dump_core") && value) {
@@ -307,6 +328,11 @@ static int parse_proc_cmdline_item(const char *key, const char *value) {
else
arg_dump_core = r;
+ } else if (streq(key, "systemd.crash_chvt") && value) {
+
+ if (parse_crash_chvt(value) < 0)
+ log_warning("Failed to parse crash chvt switch %s. Ignoring.", value);
+
} else if (streq(key, "systemd.crash_shell") && value) {
r = parse_boolean(value);
@@ -315,12 +341,13 @@ static int parse_proc_cmdline_item(const char *key, const char *value) {
else
arg_crash_shell = r;
- } else if (streq(key, "systemd.crash_chvt") && value) {
+ } else if (streq(key, "systemd.crash_reboot") && value) {
- if (safe_atoi(value, &r) < 0)
- log_warning("Failed to parse crash chvt switch %s. Ignoring.", value);
+ r = parse_boolean(value);
+ if (r < 0)
+ log_warning("Failed to parse crash reboot switch %s. Ignoring.", value);
else
- arg_crash_chvt = r;
+ arg_crash_reboot = r;
} else if (streq(key, "systemd.confirm_spawn") && value) {
@@ -384,7 +411,7 @@ static int parse_proc_cmdline_item(const char *key, const char *value) {
/* SysV compatibility */
for (i = 0; i < ELEMENTSOF(rlmap); i += 2)
if (streq(key, rlmap[i]))
- return set_default_unit(rlmap[i+1]);
+ return free_and_strdup(&arg_default_unit, rlmap[i+1]);
}
return 0;
@@ -410,9 +437,9 @@ static int parse_proc_cmdline_item(const char *key, const char *value) {
\
r = func(rvalue); \
if (r < 0) \
- log_syntax(unit, LOG_ERR, filename, line, -r, \
- "Invalid " descr "'%s': %s", \
- rvalue, strerror(-r)); \
+ log_syntax(unit, LOG_ERR, filename, line, r, \
+ "Invalid " descr "'%s': %m", \
+ rvalue); \
\
return 0; \
}
@@ -478,21 +505,32 @@ static int config_parse_show_status(
return 0;
}
-static void strv_free_free(char ***l) {
- char ***i;
+static int config_parse_crash_chvt(
+ const char* unit,
+ const char *filename,
+ unsigned line,
+ const char *section,
+ unsigned section_line,
+ const char *lvalue,
+ int ltype,
+ const char *rvalue,
+ void *data,
+ void *userdata) {
- if (!l)
- return;
+ int r;
- for (i = l; *i; i++)
- strv_free(*i);
+ assert(filename);
+ assert(lvalue);
+ assert(rvalue);
+ assert(data);
- free(l);
-}
+ r = parse_crash_chvt(rvalue);
+ if (r < 0) {
+ log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse CrashChangeVT= setting, ignoring: %s", rvalue);
+ return 0;
+ }
-static void free_join_controllers(void) {
- strv_free_free(arg_join_controllers);
- arg_join_controllers = NULL;
+ return 0;
}
static int config_parse_join_controllers(const char *unit,
@@ -513,7 +551,7 @@ static int config_parse_join_controllers(const char *unit,
assert(lvalue);
assert(rvalue);
- free_join_controllers();
+ arg_join_controllers = strv_free_free(arg_join_controllers);
for (;;) {
_cleanup_free_ char *word = NULL;
@@ -530,7 +568,7 @@ static int config_parse_join_controllers(const char *unit,
l = strv_split(word, ",");
if (!l)
- log_oom();
+ return log_oom();
strv_uniq(l);
if (strv_length(l) <= 1) {
@@ -605,9 +643,11 @@ static int parse_config_file(void) {
{ "Manager", "LogColor", config_parse_color, 0, NULL },
{ "Manager", "LogLocation", config_parse_location, 0, NULL },
{ "Manager", "DumpCore", config_parse_bool, 0, &arg_dump_core },
+ { "Manager", "CrashChVT", /* legacy */ config_parse_crash_chvt, 0, NULL },
+ { "Manager", "CrashChangeVT", config_parse_crash_chvt, 0, NULL },
{ "Manager", "CrashShell", config_parse_bool, 0, &arg_crash_shell },
+ { "Manager", "CrashReboot", config_parse_bool, 0, &arg_crash_reboot },
{ "Manager", "ShowStatus", config_parse_show_status, 0, &arg_show_status },
- { "Manager", "CrashChVT", config_parse_int, 0, &arg_crash_chvt },
{ "Manager", "CPUAffinity", config_parse_cpu_affinity2, 0, NULL },
{ "Manager", "JoinControllers", config_parse_join_controllers, 0, &arg_join_controllers },
{ "Manager", "RuntimeWatchdogSec", config_parse_sec, 0, &arg_runtime_watchdog },
@@ -695,7 +735,9 @@ static int parse_argv(int argc, char *argv[]) {
ARG_VERSION,
ARG_DUMP_CONFIGURATION_ITEMS,
ARG_DUMP_CORE,
+ ARG_CRASH_CHVT,
ARG_CRASH_SHELL,
+ ARG_CRASH_REBOOT,
ARG_CONFIRM_SPAWN,
ARG_SHOW_STATUS,
ARG_DESERIALIZE,
@@ -718,7 +760,9 @@ static int parse_argv(int argc, char *argv[]) {
{ "version", no_argument, NULL, ARG_VERSION },
{ "dump-configuration-items", no_argument, NULL, ARG_DUMP_CONFIGURATION_ITEMS },
{ "dump-core", optional_argument, NULL, ARG_DUMP_CORE },
+ { "crash-chvt", required_argument, NULL, ARG_CRASH_CHVT },
{ "crash-shell", optional_argument, NULL, ARG_CRASH_SHELL },
+ { "crash-reboot", optional_argument, NULL, ARG_CRASH_REBOOT },
{ "confirm-spawn", optional_argument, NULL, ARG_CONFIRM_SPAWN },
{ "show-status", optional_argument, NULL, ARG_SHOW_STATUS },
{ "deserialize", required_argument, NULL, ARG_DESERIALIZE },
@@ -803,7 +847,7 @@ static int parse_argv(int argc, char *argv[]) {
case ARG_UNIT:
- r = set_default_unit(optarg);
+ r = free_and_strdup(&arg_default_unit, optarg);
if (r < 0)
return log_error_errno(r, "Failed to set default unit %s: %m", optarg);
@@ -836,21 +880,42 @@ static int parse_argv(int argc, char *argv[]) {
break;
case ARG_DUMP_CORE:
- r = optarg ? parse_boolean(optarg) : 1;
- if (r < 0) {
- log_error("Failed to parse dump core boolean %s.", optarg);
- return r;
+ if (!optarg)
+ arg_dump_core = true;
+ else {
+ r = parse_boolean(optarg);
+ if (r < 0)
+ return log_error_errno(r, "Failed to parse dump core boolean: %s", optarg);
+ arg_dump_core = r;
}
- arg_dump_core = r;
+ break;
+
+ case ARG_CRASH_CHVT:
+ r = parse_crash_chvt(optarg);
+ if (r < 0)
+ return log_error_errno(r, "Failed to parse crash virtual terminal index: %s", optarg);
break;
case ARG_CRASH_SHELL:
- r = optarg ? parse_boolean(optarg) : 1;
- if (r < 0) {
- log_error("Failed to parse crash shell boolean %s.", optarg);
- return r;
+ if (!optarg)
+ arg_crash_shell = true;
+ else {
+ r = parse_boolean(optarg);
+ if (r < 0)
+ return log_error_errno(r, "Failed to parse crash shell boolean: %s", optarg);
+ arg_crash_shell = r;
+ }
+ break;
+
+ case ARG_CRASH_REBOOT:
+ if (!optarg)
+ arg_crash_reboot = true;
+ else {
+ r = parse_boolean(optarg);
+ if (r < 0)
+ return log_error_errno(r, "Failed to parse crash shell boolean: %s", optarg);
+ arg_crash_reboot = r;
}
- arg_crash_shell = r;
break;
case ARG_CONFIRM_SPAWN:
@@ -880,17 +945,16 @@ static int parse_argv(int argc, char *argv[]) {
r = safe_atoi(optarg, &fd);
if (r < 0 || fd < 0) {
log_error("Failed to parse deserialize option %s.", optarg);
- return r < 0 ? r : -EINVAL;
+ return -EINVAL;
}
- fd_cloexec(fd, true);
+ (void) fd_cloexec(fd, true);
f = fdopen(fd, "r");
if (!f)
return log_error_errno(errno, "Failed to open serialization fd: %m");
safe_fclose(arg_serialization);
-
arg_serialization = f;
break;
@@ -950,14 +1014,16 @@ static int help(void) {
" --unit=UNIT Set default unit\n"
" --system Run a system instance, even if PID != 1\n"
" --user Run a user instance\n"
- " --dump-core[=0|1] Dump core on crash\n"
- " --crash-shell[=0|1] Run shell on crash\n"
- " --confirm-spawn[=0|1] Ask for confirmation when spawning processes\n"
- " --show-status[=0|1] Show status updates on the console during bootup\n"
+ " --dump-core[=BOOL] Dump core on crash\n"
+ " --crash-vt=NR Change to specified VT on crash\n"
+ " --crash-reboot[=BOOL] Reboot on crash\n"
+ " --crash-shell[=BOOL] Run shell on crash\n"
+ " --confirm-spawn[=BOOL] Ask for confirmation when spawning processes\n"
+ " --show-status[=BOOL] Show status updates on the console during bootup\n"
" --log-target=TARGET Set log target (console, journal, kmsg, journal-or-kmsg, null)\n"
" --log-level=LEVEL Set log level (debug, info, notice, warning, err, crit, alert, emerg)\n"
- " --log-color[=0|1] Highlight important log messages\n"
- " --log-location[=0|1] Include code location in log messages\n"
+ " --log-color[=BOOL] Highlight important log messages\n"
+ " --log-location[=BOOL] Include code location in log messages\n"
" --default-standard-output= Set default standard output for services\n"
" --default-standard-error= Set default standard error output for services\n",
program_invocation_short_name);
@@ -965,16 +1031,9 @@ static int help(void) {
return 0;
}
-static int version(void) {
- puts(PACKAGE_STRING);
- puts(SYSTEMD_FEATURES);
-
- return 0;
-}
-
static int prepare_reexecute(Manager *m, FILE **_f, FDSet **_fds, bool switching_root) {
- FILE *f = NULL;
- FDSet *fds = NULL;
+ _cleanup_fdset_free_ FDSet *fds = NULL;
+ _cleanup_fclose_ FILE *f = NULL;
int r;
assert(m);
@@ -982,56 +1041,39 @@ static int prepare_reexecute(Manager *m, FILE **_f, FDSet **_fds, bool switching
assert(_fds);
r = manager_open_serialization(m, &f);
- if (r < 0) {
- log_error_errno(r, "Failed to create serialization file: %m");
- goto fail;
- }
+ if (r < 0)
+ return log_error_errno(r, "Failed to create serialization file: %m");
/* Make sure nothing is really destructed when we shut down */
m->n_reloading ++;
bus_manager_send_reloading(m, true);
fds = fdset_new();
- if (!fds) {
- r = -ENOMEM;
- log_error_errno(r, "Failed to allocate fd set: %m");
- goto fail;
- }
+ if (!fds)
+ return log_oom();
r = manager_serialize(m, f, fds, switching_root);
- if (r < 0) {
- log_error_errno(r, "Failed to serialize state: %m");
- goto fail;
- }
+ if (r < 0)
+ return log_error_errno(r, "Failed to serialize state: %m");
- if (fseeko(f, 0, SEEK_SET) < 0) {
- log_error_errno(errno, "Failed to rewind serialization fd: %m");
- goto fail;
- }
+ if (fseeko(f, 0, SEEK_SET) == (off_t) -1)
+ return log_error_errno(errno, "Failed to rewind serialization fd: %m");
r = fd_cloexec(fileno(f), false);
- if (r < 0) {
- log_error_errno(r, "Failed to disable O_CLOEXEC for serialization: %m");
- goto fail;
- }
+ if (r < 0)
+ return log_error_errno(r, "Failed to disable O_CLOEXEC for serialization: %m");
r = fdset_cloexec(fds, false);
- if (r < 0) {
- log_error_errno(r, "Failed to disable O_CLOEXEC for serialization fds: %m");
- goto fail;
- }
+ if (r < 0)
+ return log_error_errno(r, "Failed to disable O_CLOEXEC for serialization fds: %m");
*_f = f;
*_fds = fds;
- return 0;
-
-fail:
- fdset_free(fds);
-
- safe_fclose(f);
+ f = NULL;
+ fds = NULL;
- return r;
+ return 0;
}
static int bump_rlimit_nofile(struct rlimit *saved_rlimit) {
@@ -1090,7 +1132,7 @@ static void test_mtab(void) {
log_error("/etc/mtab is not a symlink or not pointing to /proc/self/mounts. "
"This is not supported anymore. "
"Please make sure to replace this file by a symlink to avoid incorrect or misleading mount(8) output.");
- freeze();
+ freeze_or_reboot();
}
static void test_usr(void) {
@@ -1116,15 +1158,19 @@ static int initialize_join_controllers(void) {
return -ENOMEM;
arg_join_controllers[0] = strv_new("cpu", "cpuacct", NULL);
- arg_join_controllers[1] = strv_new("net_cls", "net_prio", NULL);
- arg_join_controllers[2] = NULL;
+ if (!arg_join_controllers[0])
+ goto oom;
- if (!arg_join_controllers[0] || !arg_join_controllers[1]) {
- free_join_controllers();
- return -ENOMEM;
- }
+ arg_join_controllers[1] = strv_new("net_cls", "net_prio", NULL);
+ if (!arg_join_controllers[1])
+ goto oom;
+ arg_join_controllers[2] = NULL;
return 0;
+
+oom:
+ arg_join_controllers = strv_free_free(arg_join_controllers);
+ return -ENOMEM;
}
static int enforce_syscall_archs(Set *archs) {
@@ -1222,7 +1268,6 @@ int main(int argc, char *argv[]) {
char *switch_root_dir = NULL, *switch_root_init = NULL;
struct rlimit saved_rlimit_nofile = RLIMIT_MAKE_CONST(0);
const char *error_message = NULL;
- uint8_t shutdown_exit_code = 0;
#ifdef HAVE_SYSV_COMPAT
if (getpid() != 1 && strstr(program_invocation_short_name, "init")) {
@@ -1369,7 +1414,7 @@ int main(int argc, char *argv[]) {
}
/* Initialize default unit */
- r = set_default_unit(SPECIAL_DEFAULT_TARGET);
+ r = free_and_strdup(&arg_default_unit, SPECIAL_DEFAULT_TARGET);
if (r < 0) {
log_emergency_errno(r, "Failed to set default unit %s: %m", SPECIAL_DEFAULT_TARGET);
error_message = "Failed to set default unit";
@@ -1646,8 +1691,7 @@ int main(int argc, char *argv[]) {
/* This will close all file descriptors that were opened, but
* not claimed by any unit. */
- fdset_free(fds);
- fds = NULL;
+ fds = fdset_free(fds);
arg_serialization = safe_fclose(arg_serialization);
@@ -1775,8 +1819,9 @@ int main(int argc, char *argv[]) {
goto finish;
case MANAGER_EXIT:
+ retval = m->return_value;
+
if (m->running_as == MANAGER_USER) {
- retval = EXIT_SUCCESS;
log_debug("Exit.");
goto finish;
}
@@ -1809,21 +1854,17 @@ int main(int argc, char *argv[]) {
finish:
pager_close();
- if (m) {
+ if (m)
arg_shutdown_watchdog = m->shutdown_watchdog;
- shutdown_exit_code = m->return_value;
- }
+
m = manager_free(m);
for (j = 0; j < ELEMENTSOF(arg_default_rlimit); j++)
arg_default_rlimit[j] = mfree(arg_default_rlimit[j]);
arg_default_unit = mfree(arg_default_unit);
-
- free_join_controllers();
-
+ arg_join_controllers = strv_free_free(arg_join_controllers);
arg_default_environment = strv_free(arg_default_environment);
-
arg_syscall_archs = set_free(arg_syscall_archs);
mac_selinux_finish();
@@ -1841,7 +1882,7 @@ finish:
* that the new systemd can pass the kernel default to
* its child processes */
if (saved_rlimit_nofile.rlim_cur > 0)
- setrlimit(RLIMIT_NOFILE, &saved_rlimit_nofile);
+ (void) setrlimit(RLIMIT_NOFILE, &saved_rlimit_nofile);
if (switch_root_dir) {
/* Kill all remaining processes from the
@@ -1883,10 +1924,10 @@ finish:
/* do not pass along the environment we inherit from the kernel or initrd */
if (switch_root_dir)
- clearenv();
+ (void) clearenv();
assert(i <= args_size);
- execv(args[0], (char* const*) args);
+ (void) execv(args[0], (char* const*) args);
}
/* Try the fallback, if there is any, without any
@@ -1896,14 +1937,10 @@ finish:
* but let's hope that doesn't matter.) */
arg_serialization = safe_fclose(arg_serialization);
-
- if (fds) {
- fdset_free(fds);
- fds = NULL;
- }
+ fds = fdset_free(fds);
/* Reopen the console */
- make_console_stdio();
+ (void) make_console_stdio();
for (j = 1, i = 1; j < (unsigned) argc; j++)
args[i++] = argv[j];
@@ -1917,30 +1954,26 @@ finish:
if (switch_root_init) {
args[0] = switch_root_init;
- execv(args[0], (char* const*) args);
+ (void) execv(args[0], (char* const*) args);
log_warning_errno(errno, "Failed to execute configured init, trying fallback: %m");
}
args[0] = "/sbin/init";
- execv(args[0], (char* const*) args);
+ (void) execv(args[0], (char* const*) args);
if (errno == ENOENT) {
log_warning("No /sbin/init, trying fallback");
args[0] = "/bin/sh";
args[1] = NULL;
- execv(args[0], (char* const*) args);
+ (void) execv(args[0], (char* const*) args);
log_error_errno(errno, "Failed to execute /bin/sh, giving up: %m");
} else
log_warning_errno(errno, "Failed to execute /sbin/init, giving up: %m");
}
arg_serialization = safe_fclose(arg_serialization);
-
- if (fds) {
- fdset_free(fds);
- fds = NULL;
- }
+ fds = fdset_free(fds);
#ifdef HAVE_VALGRIND_VALGRIND_H
/* If we are PID 1 and running under valgrind, then let's exit
@@ -1969,6 +2002,7 @@ finish:
xsprintf(log_level, "%d", log_get_max_level());
switch (log_get_target()) {
+
case LOG_TARGET_KMSG:
case LOG_TARGET_JOURNAL_OR_KMSG:
case LOG_TARGET_SYSLOG_OR_KMSG:
@@ -1994,7 +2028,7 @@ finish:
if (streq(shutdown_verb, "exit")) {
command_line[pos++] = "--exit-code";
command_line[pos++] = exit_code;
- xsprintf(exit_code, "%d", shutdown_exit_code);
+ xsprintf(exit_code, "%d", retval);
}
assert(pos < ELEMENTSOF(command_line));
@@ -2010,7 +2044,7 @@ finish:
/* Tell the binary how often to ping, ignore failure */
if (asprintf(&e, "WATCHDOG_USEC="USEC_FMT, arg_shutdown_watchdog) > 0)
- strv_push(&env_block, e);
+ (void) strv_push(&env_block, e);
} else
watchdog_close(true);
@@ -2030,7 +2064,7 @@ finish:
manager_status_printf(NULL, STATUS_TYPE_EMERGENCY,
ANSI_HIGHLIGHT_RED "!!!!!!" ANSI_NORMAL,
"%s, freezing.", error_message);
- freeze();
+ freeze_or_reboot();
}
return retval;
diff --git a/src/core/manager.c b/src/core/manager.c
index 9bfe867ea0..9de9691a47 100644
--- a/src/core/manager.c
+++ b/src/core/manager.c
@@ -19,19 +19,19 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
+#include <dirent.h>
#include <errno.h>
-#include <string.h>
+#include <fcntl.h>
+#include <linux/kd.h>
#include <signal.h>
-#include <sys/wait.h>
-#include <unistd.h>
-#include <sys/inotify.h>
+#include <string.h>
#include <sys/epoll.h>
-#include <sys/reboot.h>
+#include <sys/inotify.h>
#include <sys/ioctl.h>
-#include <linux/kd.h>
-#include <fcntl.h>
-#include <dirent.h>
+#include <sys/reboot.h>
#include <sys/timerfd.h>
+#include <sys/wait.h>
+#include <unistd.h>
#ifdef HAVE_AUDIT
#include <libaudit.h>
@@ -40,40 +40,40 @@
#include "sd-daemon.h"
#include "sd-messages.h"
+#include "audit-fd.h"
+#include "boot-timestamps.h"
+#include "bus-common-errors.h"
+#include "bus-error.h"
+#include "bus-kernel.h"
+#include "bus-util.h"
+#include "dbus-job.h"
+#include "dbus-manager.h"
+#include "dbus-unit.h"
+#include "dbus.h"
+#include "env-util.h"
+#include "exit-status.h"
#include "hashmap.h"
-#include "macro.h"
-#include "strv.h"
+#include "locale-setup.h"
#include "log.h"
-#include "util.h"
+#include "macro.h"
+#include "missing.h"
#include "mkdir.h"
+#include "path-lookup.h"
+#include "path-util.h"
+#include "process-util.h"
#include "ratelimit.h"
-#include "locale-setup.h"
-#include "unit-name.h"
-#include "missing.h"
#include "rm-rf.h"
-#include "path-lookup.h"
+#include "signal-util.h"
#include "special.h"
-#include "exit-status.h"
+#include "strv.h"
+#include "terminal-util.h"
+#include "time-util.h"
+#include "transaction.h"
+#include "unit-name.h"
+#include "util.h"
#include "virt.h"
#include "watchdog.h"
-#include "path-util.h"
-#include "audit-fd.h"
-#include "boot-timestamps.h"
-#include "env-util.h"
-#include "bus-common-errors.h"
-#include "bus-error.h"
-#include "bus-util.h"
-#include "bus-kernel.h"
-#include "time-util.h"
-#include "process-util.h"
-#include "terminal-util.h"
-#include "signal-util.h"
-#include "dbus.h"
-#include "dbus-unit.h"
-#include "dbus-job.h"
-#include "dbus-manager.h"
#include "manager.h"
-#include "transaction.h"
/* Initial delay and the interval for printing status messages about running jobs */
#define JOBS_IN_PROGRESS_WAIT_USEC (5*USEC_PER_SEC)
diff --git a/src/core/manager.h b/src/core/manager.h
index cc0e5e3361..fad10aaacf 100644
--- a/src/core/manager.h
+++ b/src/core/manager.h
@@ -27,8 +27,8 @@
#include "sd-bus.h"
#include "sd-event.h"
-#include "fdset.h"
#include "cgroup-util.h"
+#include "fdset.h"
#include "hashmap.h"
#include "list.h"
#include "ratelimit.h"
@@ -69,11 +69,11 @@ typedef enum StatusType {
STATUS_TYPE_EMERGENCY,
} StatusType;
+#include "execute.h"
#include "job.h"
#include "path-lookup.h"
-#include "execute.h"
-#include "unit-name.h"
#include "show-status.h"
+#include "unit-name.h"
struct Manager {
/* Note that the set of units we know of is allowed to be
diff --git a/src/core/namespace.c b/src/core/namespace.c
index eb88574f8f..2b8b707df5 100644
--- a/src/core/namespace.c
+++ b/src/core/namespace.c
@@ -643,16 +643,7 @@ int setup_tmp_dirs(const char *id, char **tmp_dir, char **var_tmp_dir) {
int setup_netns(int netns_storage_socket[2]) {
_cleanup_close_ int netns = -1;
- union {
- struct cmsghdr cmsghdr;
- uint8_t buf[CMSG_SPACE(sizeof(int))];
- } control = {};
- struct msghdr mh = {
- .msg_control = &control,
- .msg_controllen = sizeof(control),
- };
- struct cmsghdr *cmsg;
- int r;
+ int r, q;
assert(netns_storage_socket);
assert(netns_storage_socket[0] >= 0);
@@ -669,12 +660,8 @@ int setup_netns(int netns_storage_socket[2]) {
if (lockf(netns_storage_socket[0], F_LOCK, 0) < 0)
return -errno;
- if (recvmsg(netns_storage_socket[0], &mh, MSG_DONTWAIT|MSG_CMSG_CLOEXEC) < 0) {
- if (errno != EAGAIN) {
- r = -errno;
- goto fail;
- }
-
+ netns = receive_one_fd(netns_storage_socket[0], MSG_DONTWAIT);
+ if (netns == -EAGAIN) {
/* Nothing stored yet, so let's create a new namespace */
if (unshare(CLONE_NEWNET) < 0) {
@@ -691,15 +678,13 @@ int setup_netns(int netns_storage_socket[2]) {
}
r = 1;
- } else {
- /* Yay, found something, so let's join the namespace */
- CMSG_FOREACH(cmsg, &mh)
- if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_RIGHTS) {
- assert(cmsg->cmsg_len == CMSG_LEN(sizeof(int)));
- netns = *(int*) CMSG_DATA(cmsg);
- }
+ } else if (netns < 0) {
+ r = netns;
+ goto fail;
+ } else {
+ /* Yay, found something, so let's join the namespace */
if (setns(netns, CLONE_NEWNET) < 0) {
r = -errno;
goto fail;
@@ -708,21 +693,14 @@ int setup_netns(int netns_storage_socket[2]) {
r = 0;
}
- cmsg = CMSG_FIRSTHDR(&mh);
- cmsg->cmsg_level = SOL_SOCKET;
- cmsg->cmsg_type = SCM_RIGHTS;
- cmsg->cmsg_len = CMSG_LEN(sizeof(int));
- memcpy(CMSG_DATA(cmsg), &netns, sizeof(int));
- mh.msg_controllen = cmsg->cmsg_len;
-
- if (sendmsg(netns_storage_socket[1], &mh, MSG_DONTWAIT|MSG_NOSIGNAL) < 0) {
- r = -errno;
+ q = send_one_fd(netns_storage_socket[1], netns, MSG_DONTWAIT);
+ if (q < 0) {
+ r = q;
goto fail;
}
fail:
lockf(netns_storage_socket[0], F_ULOCK, 0);
-
return r;
}
diff --git a/src/core/selinux-setup.c b/src/core/selinux-setup.c
index e5b457643b..ff1ea23528 100644
--- a/src/core/selinux-setup.c
+++ b/src/core/selinux-setup.c
@@ -78,14 +78,14 @@ int mac_selinux_setup(bool *loaded_policy) {
before_load = now(CLOCK_MONOTONIC);
r = selinux_init_load_policy(&enforce);
if (r == 0) {
+ _cleanup_(mac_selinux_freep) char *label = NULL;
char timespan[FORMAT_TIMESPAN_MAX];
- char *label;
mac_selinux_retest();
/* Transition to the new context */
r = mac_selinux_get_create_label_from_exe(SYSTEMD_BINARY_PATH, &label);
- if (r < 0 || label == NULL) {
+ if (r < 0 || !label) {
log_open();
log_error("Failed to compute init label, ignoring.");
} else {
@@ -94,8 +94,6 @@ int mac_selinux_setup(bool *loaded_policy) {
log_open();
if (r < 0)
log_error("Failed to transition into init label '%s', ignoring.", label);
-
- mac_selinux_free(label);
}
after_load = now(CLOCK_MONOTONIC);
diff --git a/src/core/shutdown.c b/src/core/shutdown.c
index 5296efce1d..27c581d9c1 100644
--- a/src/core/shutdown.c
+++ b/src/core/shutdown.c
@@ -430,6 +430,5 @@ int main(int argc, char *argv[]) {
error:
log_emergency_errno(r, "Critical error while doing system shutdown: %m");
-
freeze();
}
diff --git a/src/core/socket.c b/src/core/socket.c
index 54e94c4f74..0025054122 100644
--- a/src/core/socket.c
+++ b/src/core/socket.c
@@ -19,38 +19,39 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-#include <sys/stat.h>
-#include <unistd.h>
+#include <arpa/inet.h>
#include <errno.h>
#include <fcntl.h>
-#include <sys/epoll.h>
-#include <signal.h>
-#include <arpa/inet.h>
-#include <netinet/tcp.h>
#include <mqueue.h>
+#include <netinet/tcp.h>
+#include <signal.h>
+#include <sys/epoll.h>
+#include <sys/stat.h>
+#include <unistd.h>
#include "sd-event.h"
+
+#include "bus-error.h"
+#include "bus-util.h"
+#include "copy.h"
+#include "dbus-socket.h"
+#include "def.h"
+#include "exit-status.h"
+#include "formats-util.h"
+#include "label.h"
#include "log.h"
-#include "strv.h"
+#include "missing.h"
#include "mkdir.h"
#include "path-util.h"
-#include "unit-name.h"
-#include "unit-printf.h"
-#include "missing.h"
-#include "special.h"
-#include "label.h"
-#include "exit-status.h"
-#include "def.h"
-#include "smack-util.h"
-#include "bus-util.h"
-#include "bus-error.h"
#include "selinux-util.h"
-#include "dbus-socket.h"
-#include "unit.h"
-#include "formats-util.h"
#include "signal-util.h"
+#include "smack-util.h"
#include "socket.h"
-#include "copy.h"
+#include "special.h"
+#include "strv.h"
+#include "unit-name.h"
+#include "unit-printf.h"
+#include "unit.h"
static const UnitActiveState state_translation_table[_SOCKET_STATE_MAX] = {
[SOCKET_DEAD] = UNIT_INACTIVE,
@@ -955,50 +956,48 @@ static void socket_apply_fifo_options(Socket *s, int fd) {
if (s->pipe_size > 0)
if (fcntl(fd, F_SETPIPE_SZ, s->pipe_size) < 0)
- log_unit_warning_errno(UNIT(s), errno, "F_SETPIPE_SZ: %m");
+ log_unit_warning_errno(UNIT(s), errno, "Setting pipe size failed, ignoring: %m");
if (s->smack) {
r = mac_smack_apply_fd(fd, SMACK_ATTR_ACCESS, s->smack);
if (r < 0)
- log_unit_error_errno(UNIT(s), r, "mac_smack_apply_fd: %m");
+ log_unit_error_errno(UNIT(s), r, "SMACK relabelling failed, ignoring: %m");
}
}
static int fifo_address_create(
const char *path,
mode_t directory_mode,
- mode_t socket_mode,
- int *_fd) {
+ mode_t socket_mode) {
- int fd = -1, r = 0;
- struct stat st;
+ _cleanup_close_ int fd = -1;
mode_t old_mask;
+ struct stat st;
+ int r;
assert(path);
- assert(_fd);
mkdir_parents_label(path, directory_mode);
r = mac_selinux_create_file_prepare(path, S_IFIFO);
if (r < 0)
- goto fail;
+ return r;
/* Enforce the right access mode for the fifo */
old_mask = umask(~ socket_mode);
/* Include the original umask in our mask */
- umask(~socket_mode | old_mask);
+ (void) umask(~socket_mode | old_mask);
r = mkfifo(path, socket_mode);
- umask(old_mask);
+ (void) umask(old_mask);
if (r < 0 && errno != EEXIST) {
r = -errno;
goto fail;
}
- fd = open(path,
- O_RDWR | O_CLOEXEC | O_NOCTTY | O_NONBLOCK | O_NOFOLLOW);
+ fd = open(path, O_RDWR | O_CLOEXEC | O_NOCTTY | O_NONBLOCK | O_NOFOLLOW);
if (fd < 0) {
r = -errno;
goto fail;
@@ -1015,13 +1014,14 @@ static int fifo_address_create(
(st.st_mode & 0777) != (socket_mode & ~old_mask) ||
st.st_uid != getuid() ||
st.st_gid != getgid()) {
-
r = -EEXIST;
goto fail;
}
- *_fd = fd;
- return 0;
+ r = fd;
+ fd = -1;
+
+ return r;
fail:
mac_selinux_create_file_clear();
@@ -1030,51 +1030,36 @@ fail:
return r;
}
-static int special_address_create(
- const char *path,
- int *_fd) {
-
- int fd = -1, r = 0;
+static int special_address_create(const char *path) {
+ _cleanup_close_ int fd = -1;
struct stat st;
+ int r;
assert(path);
- assert(_fd);
fd = open(path, O_RDONLY|O_CLOEXEC|O_NOCTTY|O_NONBLOCK|O_NOFOLLOW);
- if (fd < 0) {
- r = -errno;
- goto fail;
- }
+ if (fd < 0)
+ return -errno;
- if (fstat(fd, &st) < 0) {
- r = -errno;
- goto fail;
- }
+ if (fstat(fd, &st) < 0)
+ return -errno;
/* Check whether this is a /proc, /sys or /dev file or char device */
- if (!S_ISREG(st.st_mode) && !S_ISCHR(st.st_mode)) {
- r = -EEXIST;
- goto fail;
- }
-
- *_fd = fd;
- return 0;
+ if (!S_ISREG(st.st_mode) && !S_ISCHR(st.st_mode))
+ return -EEXIST;
-fail:
- safe_close(fd);
+ r = fd;
+ fd = -1;
return r;
}
-static int ffs_address_create(
- const char *path,
- int *_fd) {
-
+static int usbffs_address_create(const char *path) {
_cleanup_close_ int fd = -1;
struct stat st;
+ int r;
assert(path);
- assert(_fd);
fd = open(path, O_RDWR|O_CLOEXEC|O_NOCTTY|O_NONBLOCK|O_NOFOLLOW);
if (fd < 0)
@@ -1087,32 +1072,32 @@ static int ffs_address_create(
if (!S_ISREG(st.st_mode))
return -EEXIST;
- *_fd = fd;
+ r = fd;
fd = -1;
- return 0;
+ return r;
}
static int mq_address_create(
const char *path,
mode_t mq_mode,
long maxmsg,
- long msgsize,
- int *_fd) {
+ long msgsize) {
- int fd = -1, r = 0;
+ _cleanup_close_ int fd = -1;
struct stat st;
mode_t old_mask;
struct mq_attr _attr, *attr = NULL;
+ int r;
assert(path);
- assert(_fd);
if (maxmsg > 0 && msgsize > 0) {
- zero(_attr);
- _attr.mq_flags = O_NONBLOCK;
- _attr.mq_maxmsg = maxmsg;
- _attr.mq_msgsize = msgsize;
+ _attr = (struct mq_attr) {
+ .mq_flags = O_NONBLOCK,
+ .mq_maxmsg = maxmsg,
+ .mq_msgsize = msgsize,
+ };
attr = &_attr;
}
@@ -1120,33 +1105,24 @@ static int mq_address_create(
old_mask = umask(~ mq_mode);
/* Include the original umask in our mask */
- umask(~mq_mode | old_mask);
+ (void) umask(~mq_mode | old_mask);
fd = mq_open(path, O_RDONLY|O_CLOEXEC|O_NONBLOCK|O_CREAT, mq_mode, attr);
- umask(old_mask);
+ (void) umask(old_mask);
- if (fd < 0) {
- r = -errno;
- goto fail;
- }
+ if (fd < 0)
+ return -errno;
- if (fstat(fd, &st) < 0) {
- r = -errno;
- goto fail;
- }
+ if (fstat(fd, &st) < 0)
+ return -errno;
if ((st.st_mode & 0777) != (mq_mode & ~old_mask) ||
st.st_uid != getuid() ||
- st.st_gid != getgid()) {
-
- r = -EEXIST;
- goto fail;
- }
+ st.st_gid != getgid())
+ return -EEXIST;
- *_fd = fd;
- return 0;
+ r = fd;
+ fd = -1;
-fail:
- safe_close(fd);
return r;
}
@@ -1166,8 +1142,7 @@ static int socket_symlink(Socket *s) {
return 0;
}
-static int ffs_write_descs(int fd, Unit *u) {
- Service *s = SERVICE(u);
+static int usbffs_write_descs(int fd, Service *s) {
int r;
if (!s->usb_function_descriptors || !s->usb_function_strings)
@@ -1175,27 +1150,25 @@ static int ffs_write_descs(int fd, Unit *u) {
r = copy_file_fd(s->usb_function_descriptors, fd, false);
if (r < 0)
- return 0;
-
- r = copy_file_fd(s->usb_function_strings, fd, false);
+ return r;
- return r;
+ return copy_file_fd(s->usb_function_strings, fd, false);
}
-static int select_ep(const struct dirent *d) {
+static int usbffs_select_ep(const struct dirent *d) {
return d->d_name[0] != '.' && !streq(d->d_name, "ep0");
}
-static int ffs_dispatch_eps(SocketPort *p) {
+static int usbffs_dispatch_eps(SocketPort *p) {
_cleanup_free_ struct dirent **ent = NULL;
- int r, i, n, k;
_cleanup_free_ char *path = NULL;
+ int r, i, n, k;
r = path_get_parent(p->path, &path);
if (r < 0)
return r;
- r = scandir(path, &ent, select_ep, alphasort);
+ r = scandir(path, &ent, usbffs_select_ep, alphasort);
if (r < 0)
return -errno;
@@ -1216,10 +1189,12 @@ static int ffs_dispatch_eps(SocketPort *p) {
path_kill_slashes(ep);
- r = ffs_address_create(ep, &p->auxiliary_fds[k]);
+ r = usbffs_address_create(ep);
if (r < 0)
goto fail;
+ p->auxiliary_fds[k] = r;
+
++k;
free(ent[i]);
}
@@ -1227,9 +1202,7 @@ static int ffs_dispatch_eps(SocketPort *p) {
return r;
fail:
- while (k)
- safe_close(p->auxiliary_fds[--k]);
-
+ close_many(p->auxiliary_fds, k);
p->auxiliary_fds = mfree(p->auxiliary_fds);
p->n_auxiliary_fds = 0;
@@ -1237,10 +1210,10 @@ fail:
}
static int socket_open_fds(Socket *s) {
+ _cleanup_(mac_selinux_freep) char *label = NULL;
+ bool know_label = false;
SocketPort *p;
int r;
- char *label = NULL;
- bool know_label = false;
assert(s);
@@ -1249,7 +1222,9 @@ static int socket_open_fds(Socket *s) {
if (p->fd >= 0)
continue;
- if (p->type == SOCKET_SOCKET) {
+ switch (p->type) {
+
+ case SOCKET_SOCKET:
if (!know_label) {
/* Figure out label, if we don't it know
@@ -1300,64 +1275,72 @@ static int socket_open_fds(Socket *s) {
p->fd = r;
socket_apply_socket_options(s, p->fd);
socket_symlink(s);
+ break;
- } else if (p->type == SOCKET_SPECIAL) {
+ case SOCKET_SPECIAL:
- r = special_address_create(
- p->path,
- &p->fd);
- if (r < 0)
+ p->fd = special_address_create(p->path);
+ if (p->fd < 0) {
+ r = p->fd;
goto rollback;
+ }
+ break;
- } else if (p->type == SOCKET_FIFO) {
+ case SOCKET_FIFO:
- r = fifo_address_create(
+ p->fd = fifo_address_create(
p->path,
s->directory_mode,
- s->socket_mode,
- &p->fd);
- if (r < 0)
+ s->socket_mode);
+ if (p->fd < 0) {
+ r = p->fd;
goto rollback;
+ }
socket_apply_fifo_options(s, p->fd);
socket_symlink(s);
+ break;
- } else if (p->type == SOCKET_MQUEUE) {
+ case SOCKET_MQUEUE:
- r = mq_address_create(
+ p->fd = mq_address_create(
p->path,
s->socket_mode,
s->mq_maxmsg,
- s->mq_msgsize,
- &p->fd);
- if (r < 0)
+ s->mq_msgsize);
+ if (p->fd < 0) {
+ r = p->fd;
goto rollback;
- } else if (p->type == SOCKET_USB_FUNCTION) {
+ }
+ break;
- r = ffs_address_create(
- p->path,
- &p->fd);
- if (r < 0)
+ case SOCKET_USB_FUNCTION:
+
+ p->fd = usbffs_address_create(p->path);
+ if (p->fd < 0) {
+ r = p->fd;
goto rollback;
+ }
- r = ffs_write_descs(p->fd, s->service.unit);
+ r = usbffs_write_descs(p->fd, SERVICE(UNIT_DEREF(s->service)));
if (r < 0)
goto rollback;
- r = ffs_dispatch_eps(p);
+ r = usbffs_dispatch_eps(p);
if (r < 0)
goto rollback;
- } else
+
+ break;
+
+ default:
assert_not_reached("Unknown port type");
+ }
}
- mac_selinux_free(label);
return 0;
rollback:
socket_close_fds(s);
- mac_selinux_free(label);
-
return r;
}
diff --git a/src/core/system.conf b/src/core/system.conf
index 231609033b..c30c595413 100644
--- a/src/core/system.conf
+++ b/src/core/system.conf
@@ -17,9 +17,10 @@
#LogColor=yes
#LogLocation=no
#DumpCore=yes
-#CrashShell=no
#ShowStatus=yes
-#CrashChVT=1
+#CrashChangeVT=no
+#CrashShell=no
+#CrashReboot=no
#CPUAffinity=1 2
#JoinControllers=cpu,cpuacct net_cls,net_prio
#RuntimeWatchdogSec=0
diff --git a/src/core/unit.c b/src/core/unit.c
index 3a6313e4a2..30d4e00c94 100644
--- a/src/core/unit.c
+++ b/src/core/unit.c
@@ -1129,12 +1129,12 @@ static int unit_add_slice_dependencies(Unit *u) {
return 0;
if (UNIT_ISSET(u->slice))
- return unit_add_two_dependencies(u, UNIT_AFTER, UNIT_WANTS, UNIT_DEREF(u->slice), true);
+ return unit_add_two_dependencies(u, UNIT_AFTER, UNIT_REQUIRES, UNIT_DEREF(u->slice), true);
- if (streq(u->id, SPECIAL_ROOT_SLICE))
+ if (unit_has_name(u, SPECIAL_ROOT_SLICE))
return 0;
- return unit_add_two_dependencies_by_name(u, UNIT_AFTER, UNIT_WANTS, SPECIAL_ROOT_SLICE, NULL, true);
+ return unit_add_two_dependencies_by_name(u, UNIT_AFTER, UNIT_REQUIRES, SPECIAL_ROOT_SLICE, NULL, true);
}
static int unit_add_mount_dependencies(Unit *u) {
diff --git a/src/delta/delta.c b/src/delta/delta.c
index 990130d00b..4edafc7cdf 100644
--- a/src/delta/delta.c
+++ b/src/delta/delta.c
@@ -21,21 +21,20 @@
***/
#include <errno.h>
-#include <string.h>
-#include <unistd.h>
#include <getopt.h>
+#include <string.h>
#include <sys/prctl.h>
+#include <unistd.h>
#include "hashmap.h"
-#include "util.h"
-#include "path-util.h"
#include "log.h"
#include "pager.h"
-#include "build.h"
-#include "strv.h"
+#include "path-util.h"
#include "process-util.h"
-#include "terminal-util.h"
#include "signal-util.h"
+#include "strv.h"
+#include "terminal-util.h"
+#include "util.h"
static const char prefixes[] =
"/etc\0"
@@ -544,9 +543,7 @@ static int parse_argv(int argc, char *argv[]) {
return 0;
case ARG_VERSION:
- puts(PACKAGE_STRING);
- puts(SYSTEMD_FEATURES);
- return 0;
+ return version();
case ARG_NO_PAGER:
arg_no_pager = true;
diff --git a/src/detect-virt/detect-virt.c b/src/detect-virt/detect-virt.c
index 97ae569ca5..dcf4e9749e 100644
--- a/src/detect-virt/detect-virt.c
+++ b/src/detect-virt/detect-virt.c
@@ -19,14 +19,13 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-#include <stdlib.h>
-#include <stdbool.h>
#include <errno.h>
#include <getopt.h>
+#include <stdbool.h>
+#include <stdlib.h>
#include "util.h"
#include "virt.h"
-#include "build.h"
static bool arg_quiet = false;
static enum {
@@ -75,9 +74,7 @@ static int parse_argv(int argc, char *argv[]) {
return 0;
case ARG_VERSION:
- puts(PACKAGE_STRING);
- puts(SYSTEMD_FEATURES);
- return 0;
+ return version();
case 'q':
arg_quiet = true;
@@ -99,8 +96,7 @@ static int parse_argv(int argc, char *argv[]) {
}
if (optind < argc) {
- log_error("%s takes no arguments.",
- program_invocation_short_name);
+ log_error("%s takes no arguments.", program_invocation_short_name);
return -EINVAL;
}
@@ -108,7 +104,7 @@ static int parse_argv(int argc, char *argv[]) {
}
int main(int argc, char *argv[]) {
- int retval = EXIT_SUCCESS, r;
+ int r;
/* This is mostly intended to be used for scripts which want
* to detect whether we are being run in a virtualized
@@ -126,7 +122,7 @@ int main(int argc, char *argv[]) {
case ONLY_VM:
r = detect_vm();
if (r < 0) {
- log_error_errno(r, "Failed to check for vm: %m");
+ log_error_errno(r, "Failed to check for VM: %m");
return EXIT_FAILURE;
}
@@ -155,7 +151,5 @@ int main(int argc, char *argv[]) {
if (!arg_quiet)
puts(virtualization_to_string(r));
- retval = r != VIRTUALIZATION_NONE ? EXIT_SUCCESS : EXIT_FAILURE;
-
- return retval;
+ return r != VIRTUALIZATION_NONE ? EXIT_SUCCESS : EXIT_FAILURE;
}
diff --git a/src/escape/escape.c b/src/escape/escape.c
index 341453398d..a4bfeb5df5 100644
--- a/src/escape/escape.c
+++ b/src/escape/escape.c
@@ -19,14 +19,13 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
+#include <getopt.h>
#include <stdio.h>
#include <stdlib.h>
-#include <getopt.h>
#include "log.h"
-#include "unit-name.h"
-#include "build.h"
#include "strv.h"
+#include "unit-name.h"
static enum {
ACTION_ESCAPE,
@@ -83,9 +82,7 @@ static int parse_argv(int argc, char *argv[]) {
return 0;
case ARG_VERSION:
- puts(PACKAGE_STRING);
- puts(SYSTEMD_FEATURES);
- return 0;
+ return version();
case ARG_SUFFIX:
diff --git a/src/firstboot/firstboot.c b/src/firstboot/firstboot.c
index e2a1c00a75..4f0c669ca1 100644
--- a/src/firstboot/firstboot.c
+++ b/src/firstboot/firstboot.c
@@ -19,24 +19,22 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-
#include <fcntl.h>
-#include <unistd.h>
#include <getopt.h>
#include <shadow.h>
+#include <unistd.h>
-#include "strv.h"
-#include "fileio.h"
+#include "ask-password-api.h"
#include "copy.h"
-#include "build.h"
+#include "fileio.h"
+#include "hostname-util.h"
+#include "locale-util.h"
#include "mkdir.h"
-#include "time-util.h"
#include "path-util.h"
#include "random-util.h"
-#include "locale-util.h"
-#include "ask-password-api.h"
+#include "strv.h"
#include "terminal-util.h"
-#include "hostname-util.h"
+#include "time-util.h"
static char *arg_root = NULL;
static char *arg_locale = NULL; /* $LANG */
@@ -704,9 +702,7 @@ static int parse_argv(int argc, char *argv[]) {
return 0;
case ARG_VERSION:
- puts(PACKAGE_STRING);
- puts(SYSTEMD_FEATURES);
- return 0;
+ return version();
case ARG_ROOT:
free(arg_root);
diff --git a/src/fsck/fsck.c b/src/fsck/fsck.c
index 9a7ac3250b..30c846f01d 100644
--- a/src/fsck/fsck.c
+++ b/src/fsck/fsck.c
@@ -67,7 +67,7 @@ static void start_target(const char *target, const char *mode) {
assert(target);
- r = bus_open_system_systemd(&bus);
+ r = bus_connect_system_systemd(&bus);
if (r < 0) {
log_error_errno(r, "Failed to get D-Bus connection: %m");
return;
diff --git a/src/hostname/hostnamectl.c b/src/hostname/hostnamectl.c
index dcbad99ae9..0724fcc16d 100644
--- a/src/hostname/hostnamectl.c
+++ b/src/hostname/hostnamectl.c
@@ -19,21 +19,21 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-#include <stdlib.h>
-#include <stdbool.h>
#include <getopt.h>
#include <locale.h>
+#include <stdbool.h>
+#include <stdlib.h>
#include <string.h>
#include "sd-bus.h"
#include "sd-id128.h"
-#include "hostname-util.h"
-#include "bus-util.h"
+
+#include "architecture.h"
#include "bus-error.h"
-#include "util.h"
+#include "bus-util.h"
+#include "hostname-util.h"
#include "spawn-polkit-agent.h"
-#include "build.h"
-#include "architecture.h"
+#include "util.h"
static bool arg_ask_password = true;
static BusTransport arg_transport = BUS_TRANSPORT_LOCAL;
@@ -387,9 +387,7 @@ static int parse_argv(int argc, char *argv[]) {
return 0;
case ARG_VERSION:
- puts(PACKAGE_STRING);
- puts(SYSTEMD_FEATURES);
- return 0;
+ return version();
case 'H':
arg_transport = BUS_TRANSPORT_REMOTE;
@@ -519,7 +517,7 @@ int main(int argc, char *argv[]) {
if (r <= 0)
goto finish;
- r = bus_open_transport(arg_transport, arg_host, false, &bus);
+ r = bus_connect_transport(arg_transport, arg_host, false, &bus);
if (r < 0) {
log_error_errno(r, "Failed to create bus connection: %m");
goto finish;
diff --git a/src/hwdb/hwdb.c b/src/hwdb/hwdb.c
index 446de3a2fc..1e415db845 100644
--- a/src/hwdb/hwdb.c
+++ b/src/hwdb/hwdb.c
@@ -17,21 +17,19 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-#include <stdlib.h>
+#include <ctype.h>
#include <getopt.h>
+#include <stdlib.h>
#include <string.h>
-#include <ctype.h>
-#include "util.h"
-#include "strbuf.h"
#include "conf-files.h"
-#include "strv.h"
-#include "mkdir.h"
-#include "verbs.h"
-#include "build.h"
-
#include "hwdb-internal.h"
#include "hwdb-util.h"
+#include "mkdir.h"
+#include "strbuf.h"
+#include "strv.h"
+#include "util.h"
+#include "verbs.h"
/*
* Generic udev properties, key/value database based on modalias strings.
@@ -688,9 +686,7 @@ static int parse_argv(int argc, char *argv[]) {
return 0;
case ARG_VERSION:
- puts(PACKAGE_STRING);
- puts(SYSTEMD_FEATURES);
- return 0;
+ return version();
case ARG_USR:
arg_hwdb_bin_dir = UDEVLIBEXECDIR;
diff --git a/src/import/export.c b/src/import/export.c
index b88d71fec6..d34105e4ca 100644
--- a/src/import/export.c
+++ b/src/import/export.c
@@ -22,15 +22,15 @@
#include <getopt.h>
#include "sd-event.h"
+
#include "event-util.h"
-#include "signal-util.h"
+#include "export-raw.h"
+#include "export-tar.h"
#include "hostname-util.h"
-#include "verbs.h"
-#include "build.h"
-#include "machine-image.h"
#include "import-util.h"
-#include "export-tar.h"
-#include "export-raw.h"
+#include "machine-image.h"
+#include "signal-util.h"
+#include "verbs.h"
static ImportCompressType arg_compress = IMPORT_COMPRESS_UNKNOWN;
@@ -260,9 +260,7 @@ static int parse_argv(int argc, char *argv[]) {
return help(0, NULL, NULL);
case ARG_VERSION:
- puts(PACKAGE_STRING);
- puts(SYSTEMD_FEATURES);
- return 0;
+ return version();
case ARG_FORMAT:
if (streq(optarg, "uncompressed"))
diff --git a/src/import/import.c b/src/import/import.c
index 929a840298..1c92312585 100644
--- a/src/import/import.c
+++ b/src/import/import.c
@@ -22,15 +22,15 @@
#include <getopt.h>
#include "sd-event.h"
+
#include "event-util.h"
-#include "verbs.h"
-#include "build.h"
-#include "signal-util.h"
#include "hostname-util.h"
-#include "machine-image.h"
-#include "import-util.h"
-#include "import-tar.h"
#include "import-raw.h"
+#include "import-tar.h"
+#include "import-util.h"
+#include "machine-image.h"
+#include "signal-util.h"
+#include "verbs.h"
static bool arg_force = false;
static bool arg_read_only = false;
@@ -280,9 +280,7 @@ static int parse_argv(int argc, char *argv[]) {
return help(0, NULL, NULL);
case ARG_VERSION:
- puts(PACKAGE_STRING);
- puts(SYSTEMD_FEATURES);
- return 0;
+ return version();
case ARG_FORCE:
arg_force = true;
diff --git a/src/import/importd.c b/src/import/importd.c
index c90ada5da4..a29e9d4bd5 100644
--- a/src/import/importd.c
+++ b/src/import/importd.c
@@ -600,11 +600,11 @@ static int manager_on_notify(sd_event_source *s, int fd, uint32_t revents, void
cmsg_close_all(&msghdr);
- CMSG_FOREACH(cmsg, &msghdr) {
- if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_CREDENTIALS && cmsg->cmsg_len == CMSG_LEN(sizeof(struct ucred)))
-
+ CMSG_FOREACH(cmsg, &msghdr)
+ if (cmsg->cmsg_level == SOL_SOCKET &&
+ cmsg->cmsg_type == SCM_CREDENTIALS &&
+ cmsg->cmsg_len == CMSG_LEN(sizeof(struct ucred)))
ucred = (struct ucred*) CMSG_DATA(cmsg);
- }
if (msghdr.msg_flags & MSG_TRUNC) {
log_warning("Got overly long notification datagram, ignoring.");
diff --git a/src/import/pull.c b/src/import/pull.c
index 98c22aeec9..29e9424b52 100644
--- a/src/import/pull.c
+++ b/src/import/pull.c
@@ -22,16 +22,16 @@
#include <getopt.h>
#include "sd-event.h"
+
#include "event-util.h"
-#include "verbs.h"
-#include "build.h"
-#include "signal-util.h"
#include "hostname-util.h"
-#include "machine-image.h"
#include "import-util.h"
-#include "pull-tar.h"
-#include "pull-raw.h"
+#include "machine-image.h"
#include "pull-dkr.h"
+#include "pull-raw.h"
+#include "pull-tar.h"
+#include "signal-util.h"
+#include "verbs.h"
static bool arg_force = false;
static const char *arg_image_root = "/var/lib/machines";
@@ -381,9 +381,7 @@ static int parse_argv(int argc, char *argv[]) {
return help(0, NULL, NULL);
case ARG_VERSION:
- puts(PACKAGE_STRING);
- puts(SYSTEMD_FEATURES);
- return 0;
+ return version();
case ARG_FORCE:
arg_force = true;
diff --git a/src/initctl/initctl.c b/src/initctl/initctl.c
index 6d08db74ef..2d5f7501e7 100644
--- a/src/initctl/initctl.c
+++ b/src/initctl/initctl.c
@@ -318,7 +318,7 @@ static int server_init(Server *s, unsigned n_sockets) {
s->n_fifos ++;
}
- r = bus_open_system_systemd(&s->bus);
+ r = bus_connect_system_systemd(&s->bus);
if (r < 0) {
log_error_errno(r, "Failed to get D-Bus connection: %m");
r = -EIO;
diff --git a/src/journal-remote/journal-gatewayd.c b/src/journal-remote/journal-gatewayd.c
index 4e5572db0b..29df842277 100644
--- a/src/journal-remote/journal-gatewayd.c
+++ b/src/journal-remote/journal-gatewayd.c
@@ -24,9 +24,7 @@
#include <unistd.h>
#include <fcntl.h>
#include <getopt.h>
-
#include <microhttpd.h>
-
#ifdef HAVE_GNUTLS
#include <gnutls/gnutls.h>
#endif
@@ -34,15 +32,15 @@
#include "sd-journal.h"
#include "sd-daemon.h"
#include "sd-bus.h"
-#include "log.h"
-#include "util.h"
+
#include "bus-util.h"
+#include "fileio.h"
+#include "hostname-util.h"
+#include "log.h"
#include "logs-show.h"
#include "microhttpd-util.h"
-#include "build.h"
-#include "fileio.h"
#include "sigbus.h"
-#include "hostname-util.h"
+#include "util.h"
static char *arg_key_pem = NULL;
static char *arg_cert_pem = NULL;
@@ -909,9 +907,7 @@ static int parse_argv(int argc, char *argv[]) {
return 0;
case ARG_VERSION:
- puts(PACKAGE_STRING);
- puts(SYSTEMD_FEATURES);
- return 0;
+ return version();
case ARG_KEY:
if (arg_key_pem) {
diff --git a/src/journal-remote/journal-remote.c b/src/journal-remote/journal-remote.c
index d6ebca20ec..50f41a575d 100644
--- a/src/journal-remote/journal-remote.c
+++ b/src/journal-remote/journal-remote.c
@@ -21,31 +21,30 @@
#include <errno.h>
#include <fcntl.h>
+#include <getopt.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/prctl.h>
#include <sys/socket.h>
#include <unistd.h>
-#include <getopt.h>
+
+#ifdef HAVE_GNUTLS
+#include <gnutls/gnutls.h>
+#endif
#include "sd-daemon.h"
-#include "signal-util.h"
+
+#include "conf-parser.h"
+#include "fileio.h"
#include "journal-file.h"
#include "journald-native.h"
-#include "socket-util.h"
-#include "build.h"
#include "macro.h"
+#include "signal-util.h"
+#include "socket-util.h"
#include "strv.h"
-#include "fileio.h"
-#include "conf-parser.h"
-
-#ifdef HAVE_GNUTLS
-#include <gnutls/gnutls.h>
-#endif
-
-#include "journal-remote.h"
#include "journal-remote-write.h"
+#include "journal-remote.h"
#define REMOTE_JOURNAL_PATH "/var/log/journal/remote"
@@ -1259,9 +1258,7 @@ static int parse_argv(int argc, char *argv[]) {
return 0 /* done */;
case ARG_VERSION:
- puts(PACKAGE_STRING);
- puts(SYSTEMD_FEATURES);
- return 0 /* done */;
+ return version();
case ARG_URL:
if (arg_url) {
diff --git a/src/journal-remote/journal-upload.c b/src/journal-remote/journal-upload.c
index 311bd3fdda..92ce56805a 100644
--- a/src/journal-remote/journal-upload.c
+++ b/src/journal-remote/journal-upload.c
@@ -19,22 +19,22 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-#include <stdio.h>
-#include <curl/curl.h>
-#include <sys/stat.h>
#include <fcntl.h>
#include <getopt.h>
+#include <stdio.h>
+#include <sys/stat.h>
+#include <curl/curl.h>
#include "sd-daemon.h"
-#include "log.h"
-#include "util.h"
-#include "build.h"
+
+#include "conf-parser.h"
#include "fileio.h"
+#include "formats-util.h"
+#include "log.h"
#include "mkdir.h"
-#include "conf-parser.h"
#include "sigbus.h"
-#include "formats-util.h"
#include "signal-util.h"
+#include "util.h"
#include "journal-upload.h"
#define PRIV_KEY_FILE CERTIFICATE_ROOT "/private/journal-upload.pem"
@@ -619,9 +619,7 @@ static int parse_argv(int argc, char *argv[]) {
return 0 /* done */;
case ARG_VERSION:
- puts(PACKAGE_STRING);
- puts(SYSTEMD_FEATURES);
- return 0 /* done */;
+ return version();
case 'u':
if (arg_url) {
diff --git a/src/journal/cat.c b/src/journal/cat.c
index be2c2e3354..f9b279d7de 100644
--- a/src/journal/cat.c
+++ b/src/journal/cat.c
@@ -19,17 +19,16 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-#include <stdio.h>
-#include <getopt.h>
-#include <unistd.h>
-#include <stdlib.h>
#include <errno.h>
#include <fcntl.h>
+#include <getopt.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
-#include "systemd/sd-journal.h"
+#include "sd-journal.h"
#include "util.h"
-#include "build.h"
static char *arg_identifier = NULL;
static int arg_priority = LOG_INFO;
@@ -76,9 +75,7 @@ static int parse_argv(int argc, char *argv[]) {
return 0;
case ARG_VERSION:
- puts(PACKAGE_STRING);
- puts(SYSTEMD_FEATURES);
- return 0;
+ return version();
case 't':
free(arg_identifier);
@@ -95,7 +92,7 @@ static int parse_argv(int argc, char *argv[]) {
arg_priority = log_level_from_string(optarg);
if (arg_priority < 0) {
log_error("Failed to parse priority value.");
- return arg_priority;
+ return -EINVAL;
}
break;
@@ -103,10 +100,9 @@ static int parse_argv(int argc, char *argv[]) {
int k;
k = parse_boolean(optarg);
- if (k < 0) {
- log_error("Failed to parse level prefix value.");
- return k;
- }
+ if (k < 0)
+ return log_error_errno(k, "Failed to parse level prefix value.");
+
arg_level_prefix = k;
break;
}
@@ -122,7 +118,8 @@ static int parse_argv(int argc, char *argv[]) {
}
int main(int argc, char *argv[]) {
- int r, fd = -1, saved_stderr = -1;
+ _cleanup_close_ int fd = -1, saved_stderr = -1;
+ int r;
log_parse_environment();
log_open();
@@ -133,8 +130,7 @@ int main(int argc, char *argv[]) {
fd = sd_journal_stream_fd(arg_identifier, arg_priority, arg_level_prefix);
if (fd < 0) {
- log_error_errno(fd, "Failed to create stream fd: %m");
- r = fd;
+ r = log_error_errno(fd, "Failed to create stream fd: %m");
goto finish;
}
@@ -148,25 +144,20 @@ int main(int argc, char *argv[]) {
if (fd >= 3)
safe_close(fd);
-
fd = -1;
if (argc <= optind)
- execl("/bin/cat", "/bin/cat", NULL);
+ (void) execl("/bin/cat", "/bin/cat", NULL);
else
- execvp(argv[optind], argv + optind);
-
+ (void) execvp(argv[optind], argv + optind);
r = -errno;
/* Let's try to restore a working stderr, so we can print the error message */
if (saved_stderr >= 0)
- dup3(saved_stderr, STDERR_FILENO, 0);
+ (void) dup3(saved_stderr, STDERR_FILENO, 0);
log_error_errno(r, "Failed to execute process: %m");
finish:
- safe_close(fd);
- safe_close(saved_stderr);
-
return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
}
diff --git a/src/journal/coredumpctl.c b/src/journal/coredumpctl.c
index 6628e82421..dde56008c1 100644
--- a/src/journal/coredumpctl.c
+++ b/src/journal/coredumpctl.c
@@ -19,27 +19,27 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
+#include <fcntl.h>
+#include <getopt.h>
#include <locale.h>
#include <stdio.h>
#include <string.h>
-#include <getopt.h>
-#include <fcntl.h>
#include <unistd.h>
#include "sd-journal.h"
-#include "build.h"
-#include "set.h"
-#include "util.h"
+
+#include "compress.h"
+#include "journal-internal.h"
#include "log.h"
-#include "path-util.h"
-#include "pager.h"
#include "macro.h"
-#include "journal-internal.h"
-#include "compress.h"
-#include "sigbus.h"
+#include "pager.h"
+#include "path-util.h"
#include "process-util.h"
-#include "terminal-util.h"
+#include "set.h"
+#include "sigbus.h"
#include "signal-util.h"
+#include "terminal-util.h"
+#include "util.h"
static enum {
ACTION_NONE,
@@ -175,9 +175,7 @@ static int parse_argv(int argc, char *argv[], Set *matches) {
case ARG_VERSION:
arg_action = ACTION_NONE;
- puts(PACKAGE_STRING);
- puts(SYSTEMD_FEATURES);
- return 0;
+ return version();
case ARG_NO_PAGER:
arg_no_pager = true;
diff --git a/src/journal/journal-send.c b/src/journal/journal-send.c
index 1e3a463504..dc1b2105dd 100644
--- a/src/journal/journal-send.c
+++ b/src/journal/journal-send.c
@@ -212,11 +212,6 @@ _public_ int sd_journal_sendv(const struct iovec *iov, int n) {
.msg_namelen = offsetof(struct sockaddr_un, sun_path) + strlen(sa.sun_path),
};
ssize_t k;
- union {
- struct cmsghdr cmsghdr;
- uint8_t buf[CMSG_SPACE(sizeof(int))];
- } control;
- struct cmsghdr *cmsg;
bool have_syslog_identifier = false;
bool seal = true;
@@ -335,26 +330,7 @@ _public_ int sd_journal_sendv(const struct iovec *iov, int n) {
return r;
}
- mh.msg_iov = NULL;
- mh.msg_iovlen = 0;
-
- zero(control);
- mh.msg_control = &control;
- mh.msg_controllen = sizeof(control);
-
- cmsg = CMSG_FIRSTHDR(&mh);
- cmsg->cmsg_level = SOL_SOCKET;
- cmsg->cmsg_type = SCM_RIGHTS;
- cmsg->cmsg_len = CMSG_LEN(sizeof(int));
- memcpy(CMSG_DATA(cmsg), &buffer_fd, sizeof(int));
-
- mh.msg_controllen = cmsg->cmsg_len;
-
- k = sendmsg(fd, &mh, MSG_NOSIGNAL);
- if (k < 0)
- return -errno;
-
- return 0;
+ return send_one_fd(fd, buffer_fd, 0);
}
static int fill_iovec_perror_and_send(const char *message, int skip, struct iovec iov[]) {
diff --git a/src/journal/journalctl.c b/src/journal/journalctl.c
index b38b151485..75e59dbd42 100644
--- a/src/journal/journalctl.c
+++ b/src/journal/journalctl.c
@@ -19,48 +19,47 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-#include <locale.h>
+#include <errno.h>
#include <fcntl.h>
#include <fnmatch.h>
-#include <errno.h>
+#include <getopt.h>
+#include <linux/fs.h>
+#include <locale.h>
+#include <poll.h>
+#include <signal.h>
#include <stddef.h>
-#include <string.h>
#include <stdio.h>
-#include <unistd.h>
#include <stdlib.h>
-#include <getopt.h>
-#include <signal.h>
-#include <poll.h>
-#include <sys/stat.h>
+#include <string.h>
#include <sys/inotify.h>
-#include <linux/fs.h>
+#include <sys/stat.h>
+#include <unistd.h>
-#include "sd-journal.h"
#include "sd-bus.h"
-#include "log.h"
-#include "logs-show.h"
-#include "util.h"
+#include "sd-journal.h"
+
#include "acl-util.h"
-#include "path-util.h"
+#include "bus-error.h"
+#include "bus-util.h"
+#include "catalog.h"
#include "fileio.h"
-#include "build.h"
-#include "pager.h"
-#include "strv.h"
-#include "set.h"
-#include "sigbus.h"
-#include "journal-internal.h"
+#include "fsprg.h"
+#include "hostname-util.h"
#include "journal-def.h"
-#include "journal-verify.h"
+#include "journal-internal.h"
#include "journal-qrcode.h"
#include "journal-vacuum.h"
-#include "fsprg.h"
-#include "unit-name.h"
-#include "catalog.h"
+#include "journal-verify.h"
+#include "log.h"
+#include "logs-show.h"
#include "mkdir.h"
-#include "bus-util.h"
-#include "bus-error.h"
+#include "pager.h"
+#include "path-util.h"
+#include "set.h"
+#include "sigbus.h"
+#include "strv.h"
#include "terminal-util.h"
-#include "hostname-util.h"
+#include "unit-name.h"
#define DEFAULT_FSS_INTERVAL_USEC (15*USEC_PER_MINUTE)
@@ -350,9 +349,7 @@ static int parse_argv(int argc, char *argv[]) {
return 0;
case ARG_VERSION:
- puts(PACKAGE_STRING);
- puts(SYSTEMD_FEATURES);
- return 0;
+ return version();
case ARG_NO_PAGER:
arg_no_pager = true;
@@ -1725,7 +1722,7 @@ static int flush_to_var(void) {
/* OK, let's actually do the full logic, send SIGUSR1 to the
* daemon and set up inotify to wait for the flushed file to appear */
- r = bus_open_system_systemd(&bus);
+ r = bus_connect_system_systemd(&bus);
if (r < 0)
return log_error_errno(r, "Failed to get D-Bus connection: %m");
diff --git a/src/libsystemd-network/sd-pppoe.c b/src/libsystemd-network/sd-pppoe.c
index 439d4eff38..f2baafdeb9 100644
--- a/src/libsystemd-network/sd-pppoe.c
+++ b/src/libsystemd-network/sd-pppoe.c
@@ -385,7 +385,7 @@ static int pppoe_send_initiation(sd_pppoe *ppp) {
return r;
log_debug("PPPoE: sent DISCOVER (Service-Name: %s)",
- ppp->service_name ? : "");
+ strempty(ppp->service_name));
pppoe_arm_timeout(ppp);
@@ -625,8 +625,8 @@ static int pppoe_handle_message(sd_pppoe *ppp, struct pppoe_hdr *packet, struct
mac->ether_addr_octet[3],
mac->ether_addr_octet[4],
mac->ether_addr_octet[5],
- ppp->tags.service_name ? : "",
- ppp->tags.ac_name ? : "");
+ strempty(ppp->tags.service_name),
+ strempty(ppp->tags.ac_name));
memcpy(&ppp->peer_mac, mac, ETH_ALEN);
diff --git a/src/libsystemd/libsystemd.sym b/src/libsystemd/libsystemd.sym
index 518cbbb7ed..843a1e9880 100644
--- a/src/libsystemd/libsystemd.sym
+++ b/src/libsystemd/libsystemd.sym
@@ -477,4 +477,6 @@ global:
LIBSYSTEMD_227 {
global:
sd_bus_default_flush_close;
+ sd_bus_path_decode_many;
+ sd_bus_path_encode_many;
} LIBSYSTEMD_226;
diff --git a/src/libsystemd/sd-bus/bus-container.c b/src/libsystemd/sd-bus/bus-container.c
index 5c607f49b1..435ec92d6f 100644
--- a/src/libsystemd/sd-bus/bus-container.c
+++ b/src/libsystemd/sd-bus/bus-container.c
@@ -217,15 +217,8 @@ int bus_container_connect_kernel(sd_bus *b) {
_exit(EXIT_FAILURE);
}
- cmsg = CMSG_FIRSTHDR(&mh);
- cmsg->cmsg_level = SOL_SOCKET;
- cmsg->cmsg_type = SCM_RIGHTS;
- cmsg->cmsg_len = CMSG_LEN(sizeof(int));
- memcpy(CMSG_DATA(cmsg), &fd, sizeof(int));
-
- mh.msg_controllen = cmsg->cmsg_len;
-
- if (sendmsg(pair[1], &mh, MSG_NOSIGNAL) < 0)
+ r = send_one_fd(pair[1], fd, 0);
+ if (r < 0)
_exit(EXIT_FAILURE);
_exit(EXIT_SUCCESS);
diff --git a/src/libsystemd/sd-bus/busctl.c b/src/libsystemd/sd-bus/busctl.c
index 5d07d5809c..ab8816942c 100644
--- a/src/libsystemd/sd-bus/busctl.c
+++ b/src/libsystemd/sd-bus/busctl.c
@@ -21,22 +21,21 @@
#include <getopt.h>
-#include "strv.h"
-#include "util.h"
-#include "log.h"
-#include "build.h"
-#include "pager.h"
-#include "path-util.h"
-#include "set.h"
-
#include "sd-bus.h"
-#include "bus-internal.h"
-#include "bus-util.h"
+
#include "bus-dump.h"
+#include "bus-internal.h"
#include "bus-signature.h"
#include "bus-type.h"
+#include "bus-util.h"
#include "busctl-introspect.h"
+#include "log.h"
+#include "pager.h"
+#include "path-util.h"
+#include "set.h"
+#include "strv.h"
#include "terminal-util.h"
+#include "util.h"
static bool arg_no_pager = false;
static bool arg_legend = true;
@@ -1786,9 +1785,7 @@ static int parse_argv(int argc, char *argv[]) {
return help();
case ARG_VERSION:
- puts(PACKAGE_STRING);
- puts(SYSTEMD_FEATURES);
- return 0;
+ return version();
case ARG_NO_PAGER:
arg_no_pager = true;
diff --git a/src/libsystemd/sd-bus/sd-bus.c b/src/libsystemd/sd-bus/sd-bus.c
index 53d1c6f61d..a23f7257fa 100644
--- a/src/libsystemd/sd-bus/sd-bus.c
+++ b/src/libsystemd/sd-bus/sd-bus.c
@@ -3454,6 +3454,171 @@ _public_ int sd_bus_path_decode(const char *path, const char *prefix, char **ext
return 1;
}
+_public_ int sd_bus_path_encode_many(char **out, const char *path_template, ...) {
+ _cleanup_strv_free_ char **labels = NULL;
+ char *path, *path_pos, **label_pos;
+ const char *sep, *template_pos;
+ size_t path_length;
+ va_list list;
+ int r;
+
+ assert_return(out, -EINVAL);
+ assert_return(path_template, -EINVAL);
+
+ path_length = strlen(path_template);
+
+ va_start(list, path_template);
+ for (sep = strchr(path_template, '%'); sep; sep = strchr(sep + 1, '%')) {
+ const char *arg;
+ char *label;
+
+ arg = va_arg(list, const char *);
+ if (!arg) {
+ va_end(list);
+ return -EINVAL;
+ }
+
+ label = bus_label_escape(arg);
+ if (!label) {
+ va_end(list);
+ return -ENOMEM;
+ }
+
+ r = strv_consume(&labels, label);
+ if (r < 0) {
+ va_end(list);
+ return r;
+ }
+
+ /* add label length, but account for the format character */
+ path_length += strlen(label) - 1;
+ }
+ va_end(list);
+
+ path = malloc(path_length + 1);
+ if (!path)
+ return -ENOMEM;
+
+ path_pos = path;
+ label_pos = labels;
+
+ for (template_pos = path_template; *template_pos; ) {
+ sep = strchrnul(template_pos, '%');
+ path_pos = mempcpy(path_pos, template_pos, sep - template_pos);
+ if (!*sep)
+ break;
+
+ path_pos = stpcpy(path_pos, *label_pos++);
+ template_pos = sep + 1;
+ }
+
+ *path_pos = 0;
+ *out = path;
+ return 0;
+}
+
+_public_ int sd_bus_path_decode_many(const char *path, const char *path_template, ...) {
+ _cleanup_strv_free_ char **labels = NULL;
+ const char *template_pos, *path_pos;
+ char **label_pos;
+ va_list list;
+ int r;
+
+ /*
+ * This decodes an object-path based on a template argument. The
+ * template consists of a verbatim path, optionally including special
+ * directives:
+ *
+ * - Each occurrence of '%' in the template matches an arbitrary
+ * substring of a label in the given path. At most one such
+ * directive is allowed per label. For each such directive, the
+ * caller must provide an output parameter (char **) via va_arg. If
+ * NULL is passed, the given label is verified, but not returned.
+ * For each matched label, the *decoded* label is stored in the
+ * passed output argument, and the caller is responsible to free
+ * it. Note that the output arguments are only modified if the
+ * actualy path matched the template. Otherwise, they're left
+ * untouched.
+ *
+ * This function returns <0 on error, 0 if the path does not match the
+ * template, 1 if it matched.
+ */
+
+ assert_return(path, -EINVAL);
+ assert_return(path_template, -EINVAL);
+
+ path_pos = path;
+
+ for (template_pos = path_template; *template_pos; ) {
+ const char *sep;
+ size_t length;
+ char *label;
+
+ /* verify everything until the next '%' matches verbatim */
+ sep = strchrnul(template_pos, '%');
+ length = sep - template_pos;
+ if (strncmp(path_pos, template_pos, length))
+ return 0;
+
+ path_pos += length;
+ template_pos += length;
+
+ if (!*template_pos)
+ break;
+
+ /* We found the next '%' character. Everything up until here
+ * matched. We now skip ahead to the end of this label and make
+ * sure it matches the tail of the label in the path. Then we
+ * decode the string in-between and save it for later use. */
+
+ ++template_pos; /* skip over '%' */
+
+ sep = strchrnul(template_pos, '/');
+ length = sep - template_pos; /* length of suffix to match verbatim */
+
+ /* verify the suffixes match */
+ sep = strchrnul(path_pos, '/');
+ if (sep - path_pos < (ssize_t)length ||
+ strncmp(sep - length, template_pos, length))
+ return 0;
+
+ template_pos += length; /* skip over matched label */
+ length = sep - path_pos - length; /* length of sub-label to decode */
+
+ /* store unescaped label for later use */
+ label = bus_label_unescape_n(path_pos, length);
+ if (!label)
+ return -ENOMEM;
+
+ r = strv_consume(&labels, label);
+ if (r < 0)
+ return r;
+
+ path_pos = sep; /* skip decoded label and suffix */
+ }
+
+ /* end of template must match end of path */
+ if (*path_pos)
+ return 0;
+
+ /* copy the labels over to the caller */
+ va_start(list, path_template);
+ for (label_pos = labels; label_pos && *label_pos; ++label_pos) {
+ char **arg;
+
+ arg = va_arg(list, char **);
+ if (arg)
+ *arg = *label_pos;
+ else
+ free(*label_pos);
+ }
+ va_end(list);
+
+ free(labels);
+ labels = NULL;
+ return 1;
+}
+
_public_ int sd_bus_try_close(sd_bus *bus) {
int r;
diff --git a/src/libsystemd/sd-bus/test-bus-marshal.c b/src/libsystemd/sd-bus/test-bus-marshal.c
index b203707f27..ff6bba5988 100644
--- a/src/libsystemd/sd-bus/test-bus-marshal.c
+++ b/src/libsystemd/sd-bus/test-bus-marshal.c
@@ -66,6 +66,36 @@ static void test_bus_path_encode(void) {
assert_se(sd_bus_path_decode(e, "/foo/bar", &f) > 0 && streq(f, "foo.bar"));
}
+static void test_bus_path_encode_many(void) {
+ _cleanup_free_ char *a = NULL, *b = NULL, *c = NULL, *d = NULL, *e = NULL, *f = NULL;
+
+ assert_se(sd_bus_path_decode_many("/foo/bar", "/prefix/%", NULL) == 0);
+ assert_se(sd_bus_path_decode_many("/prefix/bar", "/prefix/%bar", NULL) == 1);
+ assert_se(sd_bus_path_decode_many("/foo/bar", "/prefix/%/suffix", NULL) == 0);
+ assert_se(sd_bus_path_decode_many("/prefix/foobar/suffix", "/prefix/%/suffix", &a) == 1 && streq_ptr(a, "foobar"));
+ assert_se(sd_bus_path_decode_many("/prefix/one_foo_two/mid/three_bar_four/suffix", "/prefix/one_%_two/mid/three_%_four/suffix", &b, &c) == 1 && streq_ptr(b, "foo") && streq_ptr(c, "bar"));
+ assert_se(sd_bus_path_decode_many("/prefix/one_foo_two/mid/three_bar_four/suffix", "/prefix/one_%_two/mid/three_%_four/suffix", NULL, &d) == 1 && streq_ptr(d, "bar"));
+
+ assert_se(sd_bus_path_decode_many("/foo/bar", "/foo/bar/%", NULL) == 0);
+ assert_se(sd_bus_path_decode_many("/foo/bar/suffix", "/foo/bar%", NULL) == 0);
+ assert_se(sd_bus_path_decode_many("/foo/bar/suffix", "/foo/%/bar", NULL) == 0);
+ assert_se(sd_bus_path_decode_many("/foo/bar/suffix", "/foo/%bar", NULL) == 0);
+ assert_se(sd_bus_path_decode_many("/foo/bar/suffix", "/foo/bar/suffix") == 1);
+ assert_se(sd_bus_path_decode_many("/foo/bar/suffix", "/foo/%%/suffix", NULL, NULL) == 0); /* multiple '%' are treated verbatim */
+ assert_se(sd_bus_path_decode_many("/foo/bar/suffix", "/foo/%/suffi", NULL) == 0);
+ assert_se(sd_bus_path_decode_many("/foo/bar/suffix", "/foo/%/suffix", &e) == 1 && streq_ptr(e, "bar"));
+ assert_se(sd_bus_path_decode_many("/foo/bar/suffix", "/foo/%/%", NULL, NULL) == 1);
+ assert_se(sd_bus_path_decode_many("/foo/bar/suffix", "/%/%/%", NULL, NULL, NULL) == 1);
+ assert_se(sd_bus_path_decode_many("/foo/bar/suffix", "%/%/%", NULL, NULL, NULL) == 0);
+ assert_se(sd_bus_path_decode_many("/foo/bar/suffix", "/%/%", NULL, NULL) == 0);
+ assert_se(sd_bus_path_decode_many("/foo/bar/suffix", "/%/%/", NULL, NULL) == 0);
+ assert_se(sd_bus_path_decode_many("/foo/bar/suffix", "/%/", NULL) == 0);
+ assert_se(sd_bus_path_decode_many("/foo/bar/suffix", "/%", NULL) == 0);
+ assert_se(sd_bus_path_decode_many("/foo/bar/suffix", "%", NULL) == 0);
+
+ assert_se(sd_bus_path_encode_many(&f, "/prefix/one_%_two/mid/three_%_four/suffix", "foo", "bar") >= 0 && streq_ptr(f, "/prefix/one_foo_two/mid/three_bar_four/suffix"));
+}
+
static void test_bus_label_escape_one(const char *a, const char *b) {
_cleanup_free_ char *t = NULL, *x = NULL, *y = NULL;
@@ -393,6 +423,7 @@ int main(int argc, char *argv[]) {
test_bus_label_escape();
test_bus_path_encode();
test_bus_path_encode_unique();
+ test_bus_path_encode_many();
return 0;
}
diff --git a/src/libsystemd/sd-daemon/sd-daemon.c b/src/libsystemd/sd-daemon/sd-daemon.c
index 9ec73406c6..ba7b8da85f 100644
--- a/src/libsystemd/sd-daemon/sd-daemon.c
+++ b/src/libsystemd/sd-daemon/sd-daemon.c
@@ -498,16 +498,11 @@ _public_ int sd_notifyf(int unset_environment, const char *format, ...) {
}
_public_ int sd_booted(void) {
- struct stat st;
-
/* We test whether the runtime unit file directory has been
* created. This takes place in mount-setup.c, so is
* guaranteed to happen very early during boot. */
- if (lstat("/run/systemd/system/", &st) < 0)
- return 0;
-
- return !!S_ISDIR(st.st_mode);
+ return laccess("/run/systemd/system/", F_OK) >= 0;
}
_public_ int sd_watchdog_enabled(int unset_environment, uint64_t *usec) {
diff --git a/src/libsystemd/sd-event/sd-event.c b/src/libsystemd/sd-event/sd-event.c
index 48a5219275..1a82c4c940 100644
--- a/src/libsystemd/sd-event/sd-event.c
+++ b/src/libsystemd/sd-event/sd-event.c
@@ -242,12 +242,6 @@ static int pending_prioq_compare(const void *a, const void *b) {
if (x->pending_iteration > y->pending_iteration)
return 1;
- /* Stability for the rest */
- if (x < y)
- return -1;
- if (x > y)
- return 1;
-
return 0;
}
@@ -277,12 +271,6 @@ static int prepare_prioq_compare(const void *a, const void *b) {
if (x->priority > y->priority)
return 1;
- /* Stability for the rest */
- if (x < y)
- return -1;
- if (x > y)
- return 1;
-
return 0;
}
@@ -310,12 +298,6 @@ static int earliest_time_prioq_compare(const void *a, const void *b) {
if (x->time.next > y->time.next)
return 1;
- /* Stability for the rest */
- if (x < y)
- return -1;
- if (x > y)
- return 1;
-
return 0;
}
@@ -343,12 +325,6 @@ static int latest_time_prioq_compare(const void *a, const void *b) {
if (x->time.next + x->time.accuracy > y->time.next + y->time.accuracy)
return 1;
- /* Stability for the rest */
- if (x < y)
- return -1;
- if (x > y)
- return 1;
-
return 0;
}
@@ -370,12 +346,6 @@ static int exit_prioq_compare(const void *a, const void *b) {
if (x->priority > y->priority)
return 1;
- /* Stability for the rest */
- if (x < y)
- return -1;
- if (x > y)
- return 1;
-
return 0;
}
diff --git a/src/libsystemd/sd-hwdb/hwdb-internal.h b/src/libsystemd/sd-hwdb/hwdb-internal.h
index fedccdec72..13fddfc8ad 100644
--- a/src/libsystemd/sd-hwdb/hwdb-internal.h
+++ b/src/libsystemd/sd-hwdb/hwdb-internal.h
@@ -19,6 +19,7 @@
#pragma once
#include "sparse-endian.h"
+#include "util.h"
#define HWDB_SIG { 'K', 'S', 'L', 'P', 'H', 'H', 'R', 'H' }
diff --git a/src/locale/localectl.c b/src/locale/localectl.c
index 4a91c7420a..880a1794aa 100644
--- a/src/locale/localectl.c
+++ b/src/locale/localectl.c
@@ -20,26 +20,26 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
+#include <ftw.h>
+#include <getopt.h>
#include <locale.h>
-#include <stdlib.h>
#include <stdbool.h>
-#include <getopt.h>
+#include <stdlib.h>
#include <string.h>
-#include <ftw.h>
#include "sd-bus.h"
-#include "bus-util.h"
+
#include "bus-error.h"
-#include "util.h"
-#include "spawn-polkit-agent.h"
-#include "build.h"
-#include "strv.h"
-#include "pager.h"
-#include "set.h"
+#include "bus-util.h"
#include "def.h"
-#include "virt.h"
#include "fileio.h"
#include "locale-util.h"
+#include "pager.h"
+#include "set.h"
+#include "spawn-polkit-agent.h"
+#include "strv.h"
+#include "util.h"
+#include "virt.h"
static bool arg_no_pager = false;
static bool arg_ask_password = true;
@@ -546,9 +546,7 @@ static int parse_argv(int argc, char *argv[]) {
return 0;
case ARG_VERSION:
- puts(PACKAGE_STRING);
- puts(SYSTEMD_FEATURES);
- return 0;
+ return version();
case ARG_NO_CONVERT:
arg_convert = false;
@@ -678,7 +676,7 @@ int main(int argc, char*argv[]) {
if (r <= 0)
goto finish;
- r = bus_open_transport(arg_transport, arg_host, false, &bus);
+ r = bus_connect_transport(arg_transport, arg_host, false, &bus);
if (r < 0) {
log_error_errno(r, "Failed to create bus connection: %m");
goto finish;
diff --git a/src/login/inhibit.c b/src/login/inhibit.c
index c53ea8add7..e671341b42 100644
--- a/src/login/inhibit.c
+++ b/src/login/inhibit.c
@@ -19,21 +19,21 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
+#include <fcntl.h>
#include <getopt.h>
-#include <stdlib.h>
#include <stdio.h>
+#include <stdlib.h>
#include <unistd.h>
-#include <fcntl.h>
#include "sd-bus.h"
-#include "bus-util.h"
+
#include "bus-error.h"
-#include "util.h"
-#include "build.h"
-#include "strv.h"
+#include "bus-util.h"
#include "formats-util.h"
#include "process-util.h"
#include "signal-util.h"
+#include "strv.h"
+#include "util.h"
static const char* arg_what = "idle:sleep:shutdown";
static const char* arg_who = NULL;
@@ -179,9 +179,7 @@ static int parse_argv(int argc, char *argv[]) {
return 0;
case ARG_VERSION:
- puts(PACKAGE_STRING);
- puts(SYSTEMD_FEATURES);
- return 0;
+ return version();
case ARG_WHAT:
arg_what = optarg;
diff --git a/src/login/loginctl.c b/src/login/loginctl.c
index be52518161..bfc8716009 100644
--- a/src/login/loginctl.c
+++ b/src/login/loginctl.c
@@ -19,31 +19,31 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-#include <unistd.h>
#include <errno.h>
-#include <string.h>
#include <getopt.h>
#include <locale.h>
+#include <string.h>
+#include <unistd.h>
#include "sd-bus.h"
-#include "bus-util.h"
+
#include "bus-error.h"
+#include "bus-util.h"
+#include "cgroup-show.h"
+#include "cgroup-util.h"
#include "log.h"
-#include "util.h"
+#include "logs-show.h"
#include "macro.h"
#include "pager.h"
-#include "build.h"
+#include "process-util.h"
+#include "signal-util.h"
+#include "spawn-polkit-agent.h"
#include "strv.h"
-#include "unit-name.h"
#include "sysfs-show.h"
-#include "logs-show.h"
-#include "cgroup-show.h"
-#include "cgroup-util.h"
-#include "spawn-polkit-agent.h"
-#include "verbs.h"
-#include "process-util.h"
#include "terminal-util.h"
-#include "signal-util.h"
+#include "unit-name.h"
+#include "util.h"
+#include "verbs.h"
static char **arg_property = NULL;
static bool arg_all = false;
@@ -1416,9 +1416,7 @@ static int parse_argv(int argc, char *argv[]) {
return 0;
case ARG_VERSION:
- puts(PACKAGE_STRING);
- puts(SYSTEMD_FEATURES);
- return 0;
+ return version();
case 'p': {
r = strv_extend(&arg_property, optarg);
@@ -1544,7 +1542,7 @@ int main(int argc, char *argv[]) {
if (r <= 0)
goto finish;
- r = bus_open_transport(arg_transport, arg_host, false, &bus);
+ r = bus_connect_transport(arg_transport, arg_host, false, &bus);
if (r < 0) {
log_error_errno(r, "Failed to create bus connection: %m");
goto finish;
diff --git a/src/login/sysfs-show.c b/src/login/sysfs-show.c
index 9a9fb7622d..f38f06baf9 100644
--- a/src/login/sysfs-show.c
+++ b/src/login/sysfs-show.c
@@ -114,7 +114,7 @@ static int show_sysfs_one(
"%s%s:%s%s%s%s",
is_master ? "[MASTER] " : "",
subsystem, sysname,
- name ? " \"" : "", name ? name : "", name ? "\"" : "") < 0)
+ name ? " \"" : "", strempty(name), name ? "\"" : "") < 0)
return -ENOMEM;
free(k);
diff --git a/src/machine-id-commit/Makefile b/src/machine-id-commit/Makefile
deleted file mode 120000
index d0b0e8e008..0000000000
--- a/src/machine-id-commit/Makefile
+++ /dev/null
@@ -1 +0,0 @@
-../Makefile \ No newline at end of file
diff --git a/src/machine-id-commit/machine-id-commit.c b/src/machine-id-commit/machine-id-commit.c
deleted file mode 100644
index 0f7748e453..0000000000
--- a/src/machine-id-commit/machine-id-commit.c
+++ /dev/null
@@ -1,107 +0,0 @@
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
-/***
- This file is part of systemd.
-
- Copyright 2014 Didier Roche
-
- 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 <stdio.h>
-#include <getopt.h>
-#include <errno.h>
-
-#include "machine-id-setup.h"
-#include "log.h"
-#include "build.h"
-
-static const char *arg_root = NULL;
-
-static void help(void) {
- printf("%s [OPTIONS...]\n\n"
- "Commit a transient /etc/machine-id on disk if writable.\n\n"
- " -h --help Show this help\n"
- " --version Show package version\n"
- " --root=ROOT Filesystem root\n",
- program_invocation_short_name);
-}
-
-static int parse_argv(int argc, char *argv[]) {
-
- enum {
- ARG_VERSION = 0x100,
- ARG_ROOT,
- };
-
- static const struct option options[] = {
- { "help", no_argument, NULL, 'h' },
- { "version", no_argument, NULL, ARG_VERSION },
- { "root", required_argument, NULL, ARG_ROOT },
- {}
- };
-
- int c;
-
- assert(argc >= 0);
- assert(argv);
-
- while ((c = getopt_long(argc, argv, "hqcv", options, NULL)) >= 0)
- switch (c) {
-
- case 'h':
- help();
- return 0;
-
- case ARG_VERSION:
- puts(PACKAGE_STRING);
- puts(SYSTEMD_FEATURES);
- return 0;
-
- case ARG_ROOT:
- arg_root = optarg;
- break;
-
- case '?':
- return -EINVAL;
-
- default:
- assert_not_reached("Unhandled option");
- }
-
- if (optind < argc) {
- log_error("Extraneous arguments");
- return -EINVAL;
- }
-
- return 1;
-}
-
-int main(int argc, char *argv[]) {
- int r;
-
- log_set_target(LOG_TARGET_AUTO);
- log_parse_environment();
- log_open();
-
- r = parse_argv(argc, argv);
- if (r <= 0)
- goto finish;
-
- r = machine_id_commit(arg_root);
-
-finish:
- return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
-}
diff --git a/src/machine-id-setup/machine-id-setup-main.c b/src/machine-id-setup/machine-id-setup-main.c
index 20cb60b804..a9c4e3fadf 100644
--- a/src/machine-id-setup/machine-id-setup-main.c
+++ b/src/machine-id-setup/machine-id-setup-main.c
@@ -19,24 +19,26 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-#include <stdlib.h>
-#include <stdio.h>
-#include <getopt.h>
#include <errno.h>
+#include <getopt.h>
+#include <stdio.h>
+#include <stdlib.h>
-#include "machine-id-setup.h"
#include "log.h"
-#include "build.h"
+#include "machine-id-setup.h"
+#include "util.h"
-static const char *arg_root = "";
+static const char *arg_root = NULL;
+static bool arg_commit = false;
static void help(void) {
printf("%s [OPTIONS...]\n\n"
"Initialize /etc/machine-id from a random source.\n\n"
" -h --help Show this help\n"
" --version Show package version\n"
- " --root=ROOT Filesystem root\n",
- program_invocation_short_name);
+ " --root=ROOT Filesystem root\n"
+ " --commit Commit transient ID\n"
+ , program_invocation_short_name);
}
static int parse_argv(int argc, char *argv[]) {
@@ -44,12 +46,14 @@ static int parse_argv(int argc, char *argv[]) {
enum {
ARG_VERSION = 0x100,
ARG_ROOT,
+ ARG_COMMIT,
};
static const struct option options[] = {
{ "help", no_argument, NULL, 'h' },
{ "version", no_argument, NULL, ARG_VERSION },
{ "root", required_argument, NULL, ARG_ROOT },
+ { "commit", no_argument, NULL, ARG_COMMIT },
{}
};
@@ -67,14 +71,16 @@ static int parse_argv(int argc, char *argv[]) {
return 0;
case ARG_VERSION:
- puts(PACKAGE_STRING);
- puts(SYSTEMD_FEATURES);
- return 0;
+ return version();
case ARG_ROOT:
arg_root = optarg;
break;
+ case ARG_COMMIT:
+ arg_commit = true;
+ break;
+
case '?':
return -EINVAL;
@@ -100,5 +106,11 @@ int main(int argc, char *argv[]) {
if (r <= 0)
return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
- return machine_id_setup(arg_root) < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
+ if (arg_commit)
+ r = machine_id_commit(arg_root);
+ else
+ r = machine_id_setup(arg_root);
+
+
+ return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
}
diff --git a/src/machine/machine-dbus.c b/src/machine/machine-dbus.c
index b010c90989..21026829a9 100644
--- a/src/machine/machine-dbus.c
+++ b/src/machine/machine-dbus.c
@@ -735,7 +735,7 @@ int bus_machine_method_open_shell(sd_bus_message *message, void *userdata, sd_bu
description = strjoina("Shell for User ", isempty(user) ? "root" : user);
r = sd_bus_message_append(tm,
- "(sv)(sv)(sv)(sv)(sv)(sv)(sv)(sv)(sv)(sv)(sv)(sv)(sv)",
+ "(sv)(sv)(sv)(sv)(sv)(sv)(sv)(sv)(sv)(sv)(sv)(sv)(sv)(sv)",
"Description", "s", description,
"StandardInput", "s", "tty",
"StandardOutput", "s", "tty",
@@ -748,7 +748,8 @@ int bus_machine_method_open_shell(sd_bus_message *message, void *userdata, sd_bu
"TTYReset", "b", true,
"UtmpIdentifier", "s", utmp_id,
"UtmpMode", "s", "user",
- "PAMName", "s", "login");
+ "PAMName", "s", "login",
+ "WorkingDirectory", "s", "-~");
if (r < 0)
return r;
diff --git a/src/machine/machinectl.c b/src/machine/machinectl.c
index d276fbe956..17a186eb0e 100644
--- a/src/machine/machinectl.c
+++ b/src/machine/machinectl.c
@@ -19,44 +19,44 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-#include <sys/socket.h>
-#include <unistd.h>
+#include <arpa/inet.h>
#include <errno.h>
-#include <string.h>
+#include <fcntl.h>
#include <getopt.h>
#include <locale.h>
-#include <fcntl.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
#include <net/if.h>
+#include <netinet/in.h>
+#include <string.h>
#include <sys/mount.h>
+#include <sys/socket.h>
+#include <unistd.h>
#include "sd-bus.h"
-#include "log.h"
-#include "util.h"
-#include "macro.h"
-#include "pager.h"
-#include "spawn-polkit-agent.h"
-#include "bus-util.h"
+
#include "bus-error.h"
-#include "build.h"
-#include "strv.h"
-#include "unit-name.h"
+#include "bus-util.h"
#include "cgroup-show.h"
-#include "logs-show.h"
#include "cgroup-util.h"
-#include "ptyfwd.h"
-#include "event-util.h"
-#include "path-util.h"
-#include "mkdir.h"
#include "copy.h"
-#include "verbs.h"
+#include "env-util.h"
+#include "event-util.h"
+#include "hostname-util.h"
#include "import-util.h"
+#include "log.h"
+#include "logs-show.h"
+#include "macro.h"
+#include "mkdir.h"
+#include "pager.h"
+#include "path-util.h"
#include "process-util.h"
-#include "terminal-util.h"
+#include "ptyfwd.h"
#include "signal-util.h"
-#include "env-util.h"
-#include "hostname-util.h"
+#include "spawn-polkit-agent.h"
+#include "strv.h"
+#include "terminal-util.h"
+#include "unit-name.h"
+#include "util.h"
+#include "verbs.h"
static char **arg_property = NULL;
static bool arg_all = false;
@@ -2554,9 +2554,7 @@ static int parse_argv(int argc, char *argv[]) {
return help(0, NULL, NULL);
case ARG_VERSION:
- puts(PACKAGE_STRING);
- puts(SYSTEMD_FEATURES);
- return 0;
+ return version();
case 'p':
r = strv_extend(&arg_property, optarg);
@@ -2747,7 +2745,7 @@ int main(int argc, char*argv[]) {
if (r <= 0)
goto finish;
- r = bus_open_transport(arg_transport, arg_host, false, &bus);
+ r = bus_connect_transport(arg_transport, arg_host, false, &bus);
if (r < 0) {
log_error_errno(r, "Failed to create bus connection: %m");
goto finish;
diff --git a/src/modules-load/modules-load.c b/src/modules-load/modules-load.c
index 5bbe314ba0..55bb35b9f7 100644
--- a/src/modules-load/modules-load.c
+++ b/src/modules-load/modules-load.c
@@ -20,17 +20,16 @@
***/
#include <errno.h>
+#include <getopt.h>
+#include <limits.h>
#include <string.h>
#include <sys/stat.h>
-#include <limits.h>
-#include <getopt.h>
#include <libkmod.h>
+#include "conf-files.h"
#include "log.h"
-#include "util.h"
#include "strv.h"
-#include "conf-files.h"
-#include "build.h"
+#include "util.h"
static char **arg_proc_cmdline_modules = NULL;
@@ -199,9 +198,7 @@ static int parse_argv(int argc, char *argv[]) {
return 0;
case ARG_VERSION:
- puts(PACKAGE_STRING);
- puts(SYSTEMD_FEATURES);
- return 0;
+ return version();
case '?':
return -EINVAL;
diff --git a/src/network/networkctl.c b/src/network/networkctl.c
index 75572b6388..c78b9444b6 100644
--- a/src/network/networkctl.c
+++ b/src/network/networkctl.c
@@ -19,29 +19,28 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-#include <stdbool.h>
#include <getopt.h>
#include <net/if.h>
+#include <stdbool.h>
-#include "sd-network.h"
-#include "sd-netlink.h"
-#include "sd-hwdb.h"
#include "sd-device.h"
+#include "sd-hwdb.h"
+#include "sd-netlink.h"
+#include "sd-network.h"
-#include "strv.h"
-#include "build.h"
-#include "util.h"
-#include "pager.h"
-#include "lldp.h"
-#include "netlink-util.h"
+#include "arphrd-list.h"
#include "device-util.h"
+#include "ether-addr-util.h"
#include "hwdb-util.h"
-#include "arphrd-list.h"
+#include "lldp.h"
#include "local-addresses.h"
+#include "netlink-util.h"
+#include "pager.h"
#include "socket-util.h"
-#include "ether-addr-util.h"
-#include "verbs.h"
+#include "strv.h"
#include "terminal-util.h"
+#include "util.h"
+#include "verbs.h"
static bool arg_no_pager = false;
static bool arg_legend = true;
@@ -1063,9 +1062,7 @@ static int parse_argv(int argc, char *argv[]) {
return 0;
case ARG_VERSION:
- puts(PACKAGE_STRING);
- puts(SYSTEMD_FEATURES);
- return 0;
+ return version();
case ARG_NO_PAGER:
arg_no_pager = true;
diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c
index 5dd14b1104..db3975f466 100644
--- a/src/network/networkd-link.c
+++ b/src/network/networkd-link.c
@@ -501,10 +501,12 @@ void link_client_handler(Link *link) {
!link->ipv4ll_route)
return;
- if (link_dhcp4_enabled(link) && !link->dhcp4_configured)
- return;
-
- if (link_dhcp6_enabled(link) && !link->dhcp6_configured)
+ if ((link_dhcp4_enabled(link) && !link_dhcp6_enabled(link) &&
+ !link->dhcp4_configured) ||
+ (link_dhcp6_enabled(link) && !link_dhcp4_enabled(link) &&
+ !link->dhcp6_configured) ||
+ (link_dhcp4_enabled(link) && link_dhcp6_enabled(link) &&
+ !link->dhcp4_configured && !link->dhcp6_configured))
return;
if (link->state != LINK_STATE_CONFIGURED)
diff --git a/src/network/networkd-wait-online.c b/src/network/networkd-wait-online.c
index d958b48771..3220c4b7ef 100644
--- a/src/network/networkd-wait-online.c
+++ b/src/network/networkd-wait-online.c
@@ -21,10 +21,10 @@
#include <getopt.h>
#include "sd-daemon.h"
-#include "strv.h"
-#include "build.h"
-#include "signal-util.h"
+
#include "networkd-wait-online.h"
+#include "signal-util.h"
+#include "strv.h"
static bool arg_quiet = false;
static usec_t arg_timeout = 120 * USEC_PER_SEC;
@@ -79,9 +79,7 @@ static int parse_argv(int argc, char *argv[]) {
break;
case ARG_VERSION:
- puts(PACKAGE_STRING);
- puts(SYSTEMD_FEATURES);
- return 0;
+ return version();
case 'i':
if (strv_extend(&arg_interfaces, optarg) < 0)
diff --git a/src/notify/notify.c b/src/notify/notify.c
index 7d53cb6d75..805ea1a627 100644
--- a/src/notify/notify.c
+++ b/src/notify/notify.c
@@ -27,7 +27,6 @@
#include "sd-daemon.h"
-#include "build.h"
#include "env-util.h"
#include "formats-util.h"
#include "log.h"
@@ -85,9 +84,7 @@ static int parse_argv(int argc, char *argv[]) {
return 0;
case ARG_VERSION:
- puts(PACKAGE_STRING);
- puts(SYSTEMD_FEATURES);
- return 0;
+ return version();
case ARG_READY:
arg_ready = true;
diff --git a/src/nspawn/nspawn-expose-ports.c b/src/nspawn/nspawn-expose-ports.c
index 9e63d88b69..3658f45381 100644
--- a/src/nspawn/nspawn-expose-ports.c
+++ b/src/nspawn/nspawn-expose-ports.c
@@ -194,7 +194,7 @@ int expose_port_send_rtnl(int send_fd) {
/* Store away the fd in the socket, so that it stays open as
* long as we run the child */
- r = send_one_fd(send_fd, fd);
+ r = send_one_fd(send_fd, fd, 0);
if (r < 0)
return log_error_errno(r, "Failed to send netlink fd: %m");
@@ -214,7 +214,7 @@ int expose_port_watch_rtnl(
assert(recv_fd >= 0);
assert(ret);
- fd = receive_one_fd(recv_fd);
+ fd = receive_one_fd(recv_fd, 0);
if (fd < 0)
return log_error_errno(fd, "Failed to recv netlink fd: %m");
diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c
index 7451c2bf64..16dfe8a7c1 100644
--- a/src/nspawn/nspawn.c
+++ b/src/nspawn/nspawn.c
@@ -50,7 +50,6 @@
#include "base-filesystem.h"
#include "blkid-util.h"
#include "btrfs-util.h"
-#include "build.h"
#include "cap-list.h"
#include "capability.h"
#include "cgroup-util.h"
@@ -414,9 +413,7 @@ static int parse_argv(int argc, char *argv[]) {
return 0;
case ARG_VERSION:
- puts(PACKAGE_STRING);
- puts(SYSTEMD_FEATURES);
- return 0;
+ return version();
case 'D':
r = set_sanitized_path(&arg_directory, optarg);
@@ -1291,7 +1288,7 @@ static int setup_kmsg(const char *dest, int kmsg_socket) {
/* Store away the fd in the socket, so that it stays open as
* long as we run the child */
- r = send_one_fd(kmsg_socket, fd);
+ r = send_one_fd(kmsg_socket, fd, 0);
safe_close(fd);
if (r < 0)
@@ -2282,8 +2279,6 @@ static int wait_for_container(pid_t pid, ContainerStatus *container) {
return r;
}
-static void nop_handler(int sig) {}
-
static int on_orderly_shutdown(sd_event_source *s, const struct signalfd_siginfo *si, void *userdata) {
pid_t pid;
@@ -3241,7 +3236,7 @@ int main(int argc, char *argv[]) {
ContainerStatus container_status;
_cleanup_(barrier_destroy) Barrier barrier = BARRIER_NULL;
static const struct sigaction sa = {
- .sa_handler = nop_handler,
+ .sa_handler = nop_signal_handler,
.sa_flags = SA_NOCLDSTOP,
};
int ifi = 0;
@@ -3338,8 +3333,7 @@ int main(int argc, char *argv[]) {
barrier_set_role(&barrier, BARRIER_PARENT);
- fdset_free(fds);
- fds = NULL;
+ fds = fdset_free(fds);
kmsg_socket_pair[1] = safe_close(kmsg_socket_pair[1]);
rtnl_socket_pair[1] = safe_close(rtnl_socket_pair[1]);
diff --git a/src/path/path.c b/src/path/path.c
index f7736a4202..73b7bd2c01 100644
--- a/src/path/path.c
+++ b/src/path/path.c
@@ -19,16 +19,16 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-#include <stdio.h>
-#include <getopt.h>
#include <errno.h>
+#include <getopt.h>
+#include <stdio.h>
#include <stdlib.h>
#include "sd-path.h"
-#include "build.h"
+
+#include "log.h"
#include "macro.h"
#include "util.h"
-#include "log.h"
static const char *arg_suffix = NULL;
@@ -155,9 +155,7 @@ static int parse_argv(int argc, char *argv[]) {
return 0;
case ARG_VERSION:
- puts(PACKAGE_STRING);
- puts(SYSTEMD_FEATURES);
- return 0;
+ return version();
case ARG_SUFFIX:
arg_suffix = optarg;
diff --git a/src/resolve-host/resolve-host.c b/src/resolve-host/resolve-host.c
index 22af092cc0..97516a87a8 100644
--- a/src/resolve-host/resolve-host.c
+++ b/src/resolve-host/resolve-host.c
@@ -23,14 +23,13 @@
#include <getopt.h>
#include "sd-bus.h"
-#include "bus-util.h"
+
+#include "af-list.h"
#include "bus-error.h"
+#include "bus-util.h"
#include "in-addr-util.h"
-#include "af-list.h"
-#include "build.h"
-
-#include "resolved-dns-packet.h"
#include "resolved-def.h"
+#include "resolved-dns-packet.h"
#define DNS_CALL_TIMEOUT_USEC (45*USEC_PER_SEC)
@@ -507,9 +506,7 @@ static int parse_argv(int argc, char *argv[]) {
return 0; /* done */;
case ARG_VERSION:
- puts(PACKAGE_STRING);
- puts(SYSTEMD_FEATURES);
- return 0 /* done */;
+ return version();
case '4':
arg_family = AF_INET;
diff --git a/src/run/run.c b/src/run/run.c
index 657c6fcaf1..62687591f4 100644
--- a/src/run/run.c
+++ b/src/run/run.c
@@ -19,24 +19,24 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-#include <stdio.h>
#include <getopt.h>
+#include <stdio.h>
#include "sd-bus.h"
#include "sd-event.h"
+
+#include "bus-error.h"
#include "bus-util.h"
-#include "event-util.h"
-#include "strv.h"
-#include "build.h"
-#include "unit-name.h"
+#include "calendarspec.h"
#include "env-util.h"
+#include "event-util.h"
+#include "formats-util.h"
#include "path-util.h"
-#include "bus-error.h"
-#include "calendarspec.h"
#include "ptyfwd.h"
-#include "formats-util.h"
#include "signal-util.h"
#include "spawn-polkit-agent.h"
+#include "strv.h"
+#include "unit-name.h"
static bool arg_ask_password = true;
static bool arg_scope = false;
@@ -199,9 +199,7 @@ static int parse_argv(int argc, char *argv[]) {
break;
case ARG_VERSION:
- puts(PACKAGE_STRING);
- puts(SYSTEMD_FEATURES);
- return 0;
+ return version();
case ARG_USER:
arg_user = true;
@@ -1176,7 +1174,7 @@ int main(int argc, char* argv[]) {
arg_description = description;
}
- r = bus_open_transport_systemd(arg_transport, arg_host, arg_user, &bus);
+ r = bus_connect_transport_systemd(arg_transport, arg_host, arg_user, &bus);
if (r < 0) {
log_error_errno(r, "Failed to create bus connection: %m");
goto finish;
diff --git a/src/shared/ask-password-api.h b/src/shared/ask-password-api.h
index 0954e072be..ccb3be0fca 100644
--- a/src/shared/ask-password-api.h
+++ b/src/shared/ask-password-api.h
@@ -21,6 +21,9 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
+#include <stdbool.h>
+
+#include "time-util.h"
int ask_password_tty(const char *message, usec_t until, bool echo, const char *flag_file, char **_passphrase);
diff --git a/src/shared/bus-util.c b/src/shared/bus-util.c
index 16b17c2c82..10df3fc3d6 100644
--- a/src/shared/bus-util.c
+++ b/src/shared/bus-util.c
@@ -574,14 +574,14 @@ int bus_check_peercred(sd_bus *c) {
return 1;
}
-int bus_open_system_systemd(sd_bus **_bus) {
+int bus_connect_system_systemd(sd_bus **_bus) {
_cleanup_bus_unref_ sd_bus *bus = NULL;
int r;
assert(_bus);
if (geteuid() != 0)
- return sd_bus_open_system(_bus);
+ return sd_bus_default_system(_bus);
/* If we are root and kdbus is not available, then let's talk
* directly to the system instance, instead of going via the
@@ -616,7 +616,7 @@ int bus_open_system_systemd(sd_bus **_bus) {
r = sd_bus_start(bus);
if (r < 0)
- return sd_bus_open_system(_bus);
+ return sd_bus_default_system(_bus);
r = bus_check_peercred(bus);
if (r < 0)
@@ -628,7 +628,7 @@ int bus_open_system_systemd(sd_bus **_bus) {
return 0;
}
-int bus_open_user_systemd(sd_bus **_bus) {
+int bus_connect_user_systemd(sd_bus **_bus) {
_cleanup_bus_unref_ sd_bus *bus = NULL;
_cleanup_free_ char *ee = NULL;
const char *e;
@@ -658,7 +658,7 @@ int bus_open_user_systemd(sd_bus **_bus) {
e = secure_getenv("XDG_RUNTIME_DIR");
if (!e)
- return sd_bus_open_user(_bus);
+ return sd_bus_default_user(_bus);
ee = bus_address_escape(e);
if (!ee)
@@ -674,7 +674,7 @@ int bus_open_user_systemd(sd_bus **_bus) {
r = sd_bus_start(bus);
if (r < 0)
- return sd_bus_open_user(_bus);
+ return sd_bus_default_user(_bus);
r = bus_check_peercred(bus);
if (r < 0)
@@ -1209,7 +1209,7 @@ int bus_map_all_properties(
return bus_message_map_all_properties(m, map, userdata);
}
-int bus_open_transport(BusTransport transport, const char *host, bool user, sd_bus **bus) {
+int bus_connect_transport(BusTransport transport, const char *host, bool user, sd_bus **bus) {
int r;
assert(transport >= 0);
@@ -1244,7 +1244,7 @@ int bus_open_transport(BusTransport transport, const char *host, bool user, sd_b
return r;
}
-int bus_open_transport_systemd(BusTransport transport, const char *host, bool user, sd_bus **bus) {
+int bus_connect_transport_systemd(BusTransport transport, const char *host, bool user, sd_bus **bus) {
int r;
assert(transport >= 0);
@@ -1258,9 +1258,9 @@ int bus_open_transport_systemd(BusTransport transport, const char *host, bool us
case BUS_TRANSPORT_LOCAL:
if (user)
- r = bus_open_user_systemd(bus);
+ r = bus_connect_user_systemd(bus);
else
- r = bus_open_system_systemd(bus);
+ r = bus_connect_system_systemd(bus);
break;
diff --git a/src/shared/bus-util.h b/src/shared/bus-util.h
index d2b2d701ce..f03f951dc7 100644
--- a/src/shared/bus-util.h
+++ b/src/shared/bus-util.h
@@ -65,11 +65,11 @@ int bus_test_polkit(sd_bus_message *call, int capability, const char *action, co
int bus_verify_polkit_async(sd_bus_message *call, int capability, const char *action, const char **details, bool interactive, uid_t good_user, Hashmap **registry, sd_bus_error *error);
void bus_verify_polkit_async_registry_free(Hashmap *registry);
-int bus_open_system_systemd(sd_bus **_bus);
-int bus_open_user_systemd(sd_bus **_bus);
+int bus_connect_system_systemd(sd_bus **_bus);
+int bus_connect_user_systemd(sd_bus **_bus);
-int bus_open_transport(BusTransport transport, const char *host, bool user, sd_bus **bus);
-int bus_open_transport_systemd(BusTransport transport, const char *host, bool user, sd_bus **bus);
+int bus_connect_transport(BusTransport transport, const char *host, bool user, sd_bus **bus);
+int bus_connect_transport_systemd(BusTransport transport, const char *host, bool user, sd_bus **bus);
int bus_print_property(const char *name, sd_bus_message *property, bool all);
int bus_print_all_properties(sd_bus *bus, const char *dest, const char *path, char **filter, bool all);
diff --git a/src/shared/pager.c b/src/shared/pager.c
index 41da820938..d8f0fb404d 100644
--- a/src/shared/pager.c
+++ b/src/shared/pager.c
@@ -48,24 +48,27 @@ noreturn static void pager_fallback(void) {
}
int pager_open(bool jump_to_end) {
- int fd[2];
+ _cleanup_close_pair_ int fd[2] = { -1, -1 };
const char *pager;
pid_t parent_pid;
- int r;
if (pager_pid > 0)
return 1;
- if ((pager = getenv("SYSTEMD_PAGER")) || (pager = getenv("PAGER")))
- if (!*pager || streq(pager, "cat"))
- return 0;
-
if (!on_tty())
return 0;
+ pager = getenv("SYSTEMD_PAGER");
+ if (!pager)
+ pager = getenv("PAGER");
+
+ /* If the pager is explicitly turned off, honour it */
+ if (pager && (pager[0] == 0 || streq(pager, "cat")))
+ return 0;
+
/* Determine and cache number of columns before we spawn the
* pager so that we get the value from the actual tty */
- columns();
+ (void) columns();
if (pipe(fd) < 0)
return log_error_errno(errno, "Failed to create pager pipe: %m");
@@ -73,11 +76,8 @@ int pager_open(bool jump_to_end) {
parent_pid = getpid();
pager_pid = fork();
- if (pager_pid < 0) {
- r = log_error_errno(errno, "Failed to fork pager: %m");
- safe_close_pair(fd);
- return r;
- }
+ if (pager_pid < 0)
+ return log_error_errno(errno, "Failed to fork pager: %m");
/* In the child start the pager */
if (pager_pid == 0) {
@@ -86,7 +86,7 @@ int pager_open(bool jump_to_end) {
(void) reset_all_signal_handlers();
(void) reset_signal_mask();
- dup2(fd[0], STDIN_FILENO);
+ (void) dup2(fd[0], STDIN_FILENO);
safe_close_pair(fd);
/* Initialize a good set of less options */
@@ -141,7 +141,6 @@ int pager_open(bool jump_to_end) {
if (dup2(fd[1], STDERR_FILENO) < 0)
return log_error_errno(errno, "Failed to duplicate pager pipe: %m");
- safe_close_pair(fd);
return 1;
}
diff --git a/src/shared/sysctl-util.c b/src/shared/sysctl-util.c
index 1de0b94fd5..b2cab948ef 100644
--- a/src/shared/sysctl-util.c
+++ b/src/shared/sysctl-util.c
@@ -19,18 +19,17 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-#include <stdlib.h>
-#include <stdbool.h>
#include <errno.h>
-#include <string.h>
-#include <stdio.h>
-#include <limits.h>
#include <getopt.h>
+#include <limits.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "fileio.h"
#include "log.h"
#include "util.h"
-#include "fileio.h"
-#include "build.h"
#include "sysctl-util.h"
char *sysctl_normalize(char *s) {
diff --git a/src/sleep/sleep.c b/src/sleep/sleep.c
index 2b2310152d..1ba66eb998 100644
--- a/src/sleep/sleep.c
+++ b/src/sleep/sleep.c
@@ -20,18 +20,18 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-#include <stdio.h>
#include <errno.h>
#include <getopt.h>
+#include <stdio.h>
#include "sd-messages.h"
-#include "log.h"
-#include "util.h"
-#include "strv.h"
+
+#include "def.h"
#include "fileio.h"
-#include "build.h"
+#include "log.h"
#include "sleep-config.h"
-#include "def.h"
+#include "strv.h"
+#include "util.h"
static char* arg_verb = NULL;
@@ -165,9 +165,7 @@ static int parse_argv(int argc, char *argv[]) {
return 0; /* done */
case ARG_VERSION:
- puts(PACKAGE_STRING);
- puts(SYSTEMD_FEATURES);
- return 0 /* done */;
+ return version();
case '?':
return -EINVAL;
diff --git a/src/socket-proxy/socket-proxyd.c b/src/socket-proxy/socket-proxyd.c
index 715f440cb1..73c04fdfc0 100644
--- a/src/socket-proxy/socket-proxyd.c
+++ b/src/socket-proxy/socket-proxyd.c
@@ -20,12 +20,12 @@
***/
#include <errno.h>
+#include <fcntl.h>
#include <getopt.h>
+#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include <netdb.h>
-#include <fcntl.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <unistd.h>
@@ -33,12 +33,12 @@
#include "sd-daemon.h"
#include "sd-event.h"
#include "sd-resolve.h"
+
#include "log.h"
+#include "path-util.h"
+#include "set.h"
#include "socket-util.h"
#include "util.h"
-#include "build.h"
-#include "set.h"
-#include "path-util.h"
#define BUFFER_SIZE (256 * 1024)
#define CONNECTIONS_MAX 256
@@ -603,9 +603,7 @@ static int parse_argv(int argc, char *argv[]) {
return 0;
case ARG_VERSION:
- puts(PACKAGE_STRING);
- puts(SYSTEMD_FEATURES);
- return 0;
+ return version();
case '?':
return -EINVAL;
diff --git a/src/sysctl/sysctl.c b/src/sysctl/sysctl.c
index 618844382f..ee34209a30 100644
--- a/src/sysctl/sysctl.c
+++ b/src/sysctl/sysctl.c
@@ -19,23 +19,22 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-#include <stdlib.h>
-#include <stdbool.h>
#include <errno.h>
-#include <string.h>
-#include <stdio.h>
-#include <limits.h>
#include <getopt.h>
+#include <limits.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
-#include "log.h"
-#include "strv.h"
-#include "util.h"
-#include "hashmap.h"
-#include "path-util.h"
#include "conf-files.h"
#include "fileio.h"
-#include "build.h"
+#include "hashmap.h"
+#include "log.h"
+#include "path-util.h"
+#include "strv.h"
#include "sysctl-util.h"
+#include "util.h"
static char **arg_prefixes = NULL;
@@ -195,9 +194,7 @@ static int parse_argv(int argc, char *argv[]) {
return 0;
case ARG_VERSION:
- puts(PACKAGE_STRING);
- puts(SYSTEMD_FEATURES);
- return 0;
+ return version();
case ARG_PREFIX: {
char *p;
diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c
index 34e4751b94..9718ef54df 100644
--- a/src/systemctl/systemctl.c
+++ b/src/systemctl/systemctl.c
@@ -37,7 +37,6 @@
#include "sd-daemon.h"
#include "sd-login.h"
-#include "build.h"
#include "bus-common-errors.h"
#include "bus-error.h"
#include "bus-message.h"
@@ -74,6 +73,7 @@
#include "unit-name.h"
#include "util.h"
#include "utmp-wtmp.h"
+#include "verbs.h"
static char **arg_types = NULL;
static char **arg_states = NULL;
@@ -134,23 +134,61 @@ static enum action {
_ACTION_MAX
} arg_action = ACTION_SYSTEMCTL;
static BusTransport arg_transport = BUS_TRANSPORT_LOCAL;
-static char *arg_host = NULL;
+static const char *arg_host = NULL;
static unsigned arg_lines = 10;
static OutputMode arg_output = OUTPUT_SHORT;
static bool arg_plain = false;
static bool arg_firmware_setup = false;
static bool arg_now = false;
-static bool original_stdout_is_tty;
-
-static int daemon_reload(sd_bus *bus, char **args);
+static int daemon_reload(int argc, char *argv[], void* userdata);
static int halt_now(enum action a);
static int check_one_unit(sd_bus *bus, const char *name, const char *good_states, bool quiet);
-static char** strv_skip_first(char **strv) {
- if (strv_length(strv) > 0)
- return strv + 1;
- return NULL;
+static bool original_stdout_is_tty;
+
+typedef enum BusFocus {
+ BUS_FULL, /* The full bus indicated via --system or --user */
+ BUS_MANAGER, /* The manager itself, possibly directly, possibly via the bus */
+ _BUS_FOCUS_MAX
+} BusFocus;
+
+static sd_bus *busses[_BUS_FOCUS_MAX] = {};
+
+static int acquire_bus(BusFocus focus, sd_bus **ret) {
+ int r;
+
+ assert(focus < _BUS_FOCUS_MAX);
+ assert(ret);
+
+ /* We only go directly to the manager, if we are using a local transport */
+ if (arg_transport != BUS_TRANSPORT_LOCAL)
+ focus = BUS_FULL;
+
+ if (!busses[focus]) {
+ bool user;
+
+ user = arg_scope != UNIT_FILE_SYSTEM;
+
+ if (focus == BUS_MANAGER)
+ r = bus_connect_transport_systemd(arg_transport, arg_host, user, &busses[focus]);
+ else
+ r = bus_connect_transport(arg_transport, arg_host, user, &busses[focus]);
+ if (r < 0)
+ return log_error_errno(r, "Failed to connect to bus: %m");
+
+ (void) sd_bus_set_allow_interactive_authorization(busses[focus], arg_ask_password);
+ }
+
+ *ret = busses[focus];
+ return 0;
+}
+
+static void release_busses(void) {
+ BusFocus w;
+
+ for (w = 0; w < _BUS_FOCUS_MAX; w++)
+ busses[w] = sd_bus_flush_close_unref(busses[w]);
}
static void pager_open_if_enabled(void) {
@@ -230,42 +268,10 @@ static int translate_bus_error_to_exit_status(int r, const sd_bus_error *error)
return EXIT_FAILURE;
}
-static void warn_wall(enum action a) {
- static const char *table[_ACTION_MAX] = {
- [ACTION_HALT] = "The system is going down for system halt NOW!",
- [ACTION_REBOOT] = "The system is going down for reboot NOW!",
- [ACTION_POWEROFF] = "The system is going down for power-off NOW!",
- [ACTION_KEXEC] = "The system is going down for kexec reboot NOW!",
- [ACTION_RESCUE] = "The system is going down to rescue mode NOW!",
- [ACTION_EMERGENCY] = "The system is going down to emergency mode NOW!",
- [ACTION_CANCEL_SHUTDOWN] = "The system shutdown has been cancelled NOW!"
- };
-
- if (arg_no_wall)
- return;
-
- if (arg_wall) {
- _cleanup_free_ char *p;
-
- p = strv_join(arg_wall, " ");
- if (!p) {
- log_oom();
- return;
- }
-
- if (*p) {
- utmp_wall(p, NULL, NULL, NULL, NULL);
- return;
- }
- }
+static bool install_client_side(void) {
- if (!table[a])
- return;
-
- utmp_wall(table[a], NULL, NULL, NULL, NULL);
-}
-
-static bool avoid_bus(void) {
+ /* Decides when to execute enable/disable/... operations
+ * client-side rather than server-side. */
if (running_in_chroot() > 0)
return true;
@@ -652,15 +658,20 @@ static int get_unit_list_recursive(
return c;
}
-static int list_units(sd_bus *bus, char **args) {
+static int list_units(int argc, char *argv[], void *userdata) {
_cleanup_free_ UnitInfo *unit_infos = NULL;
_cleanup_(message_set_freep) Set *replies = NULL;
_cleanup_strv_free_ char **machines = NULL;
+ sd_bus *bus;
int r;
pager_open_if_enabled();
- r = get_unit_list_recursive(bus, strv_skip_first(args), &unit_infos, &replies, &machines);
+ r = acquire_bus(BUS_MANAGER, &bus);
+ if (r < 0)
+ return r;
+
+ r = get_unit_list_recursive(bus, strv_skip(argv, 1), &unit_infos, &replies, &machines);
if (r < 0)
return r;
@@ -676,6 +687,10 @@ static int get_triggered_units(
_cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
int r;
+ assert(bus);
+ assert(path);
+ assert(ret);
+
r = sd_bus_get_property_strv(
bus,
"org.freedesktop.systemd1",
@@ -684,9 +699,8 @@ static int get_triggered_units(
"Triggers",
&error,
ret);
-
if (r < 0)
- log_error("Failed to determine triggers: %s", bus_error_message(&error, r));
+ return log_error_errno(r, "Failed to determine triggers: %s", bus_error_message(&error, r));
return 0;
}
@@ -710,10 +724,8 @@ static int get_listening(
&error,
&reply,
"a(ss)");
- if (r < 0) {
- log_error("Failed to get list of listening sockets: %s", bus_error_message(&error, r));
- return r;
- }
+ if (r < 0)
+ return log_error_errno(r, "Failed to get list of listening sockets: %s", bus_error_message(&error, r));
r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ss)");
if (r < 0)
@@ -853,7 +865,7 @@ static int output_sockets_list(struct socket_info *socket_infos, unsigned cs) {
return 0;
}
-static int list_sockets(sd_bus *bus, char **args) {
+static int list_sockets(int argc, char *argv[], void *userdata) {
_cleanup_(message_set_freep) Set *replies = NULL;
_cleanup_strv_free_ char **machines = NULL;
_cleanup_free_ UnitInfo *unit_infos = NULL;
@@ -863,10 +875,15 @@ static int list_sockets(sd_bus *bus, char **args) {
unsigned cs = 0;
size_t size = 0;
int r = 0, n;
+ sd_bus *bus;
pager_open_if_enabled();
- n = get_unit_list_recursive(bus, strv_skip_first(args), &unit_infos, &replies, &machines);
+ r = acquire_bus(BUS_MANAGER, &bus);
+ if (r < 0)
+ return r;
+
+ n = get_unit_list_recursive(bus, strv_skip(argv, 1), &unit_infos, &replies, &machines);
if (n < 0)
return n;
@@ -947,10 +964,8 @@ static int get_next_elapse(
&error,
't',
&t.monotonic);
- if (r < 0) {
- log_error("Failed to get next elapsation time: %s", bus_error_message(&error, r));
- return r;
- }
+ if (r < 0)
+ return log_error_errno(r, "Failed to get next elapsation time: %s", bus_error_message(&error, r));
r = sd_bus_get_property_trivial(
bus,
@@ -961,10 +976,8 @@ static int get_next_elapse(
&error,
't',
&t.realtime);
- if (r < 0) {
- log_error("Failed to get next elapsation time: %s", bus_error_message(&error, r));
- return r;
- }
+ if (r < 0)
+ return log_error_errno(r, "Failed to get next elapsation time: %s", bus_error_message(&error, r));
*next = t;
return 0;
@@ -991,10 +1004,8 @@ static int get_last_trigger(
&error,
't',
last);
- if (r < 0) {
- log_error("Failed to get last trigger time: %s", bus_error_message(&error, r));
- return r;
- }
+ if (r < 0)
+ return log_error_errno(r, "Failed to get last trigger time: %s", bus_error_message(&error, r));
return 0;
}
@@ -1160,7 +1171,7 @@ static usec_t calc_next_elapse(dual_timestamp *nw, dual_timestamp *next) {
return next_elapse;
}
-static int list_timers(sd_bus *bus, char **args) {
+static int list_timers(int argc, char *argv[], void *userdata) {
_cleanup_(message_set_freep) Set *replies = NULL;
_cleanup_strv_free_ char **machines = NULL;
_cleanup_free_ struct timer_info *timer_infos = NULL;
@@ -1170,11 +1181,16 @@ static int list_timers(sd_bus *bus, char **args) {
size_t size = 0;
int n, c = 0;
dual_timestamp nw;
+ sd_bus *bus;
int r = 0;
pager_open_if_enabled();
- n = get_unit_list_recursive(bus, strv_skip_first(args), &unit_infos, &replies, &machines);
+ r = acquire_bus(BUS_MANAGER, &bus);
+ if (r < 0)
+ return r;
+
+ n = get_unit_list_recursive(bus, strv_skip(argv, 1), &unit_infos, &replies, &machines);
if (n < 0)
return n;
@@ -1326,7 +1342,7 @@ static void output_unit_file_list(const UnitFileList *units, unsigned c) {
printf("\n%u unit files listed.\n", c);
}
-static int list_unit_files(sd_bus *bus, char **args) {
+static int list_unit_files(int argc, char *argv[], void *userdata) {
_cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
_cleanup_free_ UnitFileList *units = NULL;
UnitFileList *unit;
@@ -1338,7 +1354,7 @@ static int list_unit_files(sd_bus *bus, char **args) {
pager_open_if_enabled();
- if (avoid_bus()) {
+ if (install_client_side()) {
Hashmap *h;
UnitFileList *u;
Iterator i;
@@ -1351,8 +1367,7 @@ static int list_unit_files(sd_bus *bus, char **args) {
r = unit_file_get_list(arg_scope, arg_root, h);
if (r < 0) {
unit_file_list_free(h);
- log_error_errno(r, "Failed to get unit file list: %m");
- return r;
+ return log_error_errno(r, "Failed to get unit file list: %m");
}
n_units = hashmap_size(h);
@@ -1364,7 +1379,7 @@ static int list_unit_files(sd_bus *bus, char **args) {
}
HASHMAP_FOREACH(u, h, i) {
- if (!output_show_unit_file(u, strv_skip_first(args)))
+ if (!output_show_unit_file(u, strv_skip(argv, 1)))
continue;
units[c++] = *u;
@@ -1375,6 +1390,11 @@ static int list_unit_files(sd_bus *bus, char **args) {
hashmap_free(h);
} else {
_cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
+ sd_bus *bus;
+
+ r = acquire_bus(BUS_MANAGER, &bus);
+ if (r < 0)
+ return r;
r = sd_bus_call_method(
bus,
@@ -1385,10 +1405,8 @@ static int list_unit_files(sd_bus *bus, char **args) {
&error,
&reply,
NULL);
- if (r < 0) {
- log_error("Failed to list unit files: %s", bus_error_message(&error, r));
- return r;
- }
+ if (r < 0)
+ return log_error_errno(r, "Failed to list unit files: %s", bus_error_message(&error, r));
r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ss)");
if (r < 0)
@@ -1404,7 +1422,7 @@ static int list_unit_files(sd_bus *bus, char **args) {
unit_file_state_from_string(state)
};
- if (output_show_unit_file(&units[c], strv_skip_first(args)))
+ if (output_show_unit_file(&units[c], strv_skip(argv, 1)))
c ++;
}
@@ -1419,7 +1437,7 @@ static int list_unit_files(sd_bus *bus, char **args) {
qsort_safe(units, c, sizeof(UnitFileList), compare_unit_file_list);
output_unit_file_list(units, c);
- if (avoid_bus()) {
+ if (install_client_side()) {
for (unit = units; unit < units + c; unit++)
free(unit->path);
}
@@ -1511,10 +1529,8 @@ static int list_dependencies_get_dependencies(sd_bus *bus, const char *name, cha
&error,
&reply,
"s", "org.freedesktop.systemd1.Unit");
- if (r < 0) {
- log_error("Failed to get properties of %s: %s", name, bus_error_message(&error, r));
- return r;
- }
+ if (r < 0)
+ return log_error_errno(r, "Failed to get properties of %s: %s", name, bus_error_message(&error, r));
r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "{sv}");
if (r < 0)
@@ -1638,16 +1654,15 @@ static int list_dependencies_one(
return 0;
}
-static int list_dependencies(sd_bus *bus, char **args) {
+static int list_dependencies(int argc, char *argv[], void *userdata) {
_cleanup_strv_free_ char **units = NULL;
_cleanup_free_ char *unit = NULL;
const char *u;
+ sd_bus *bus;
int r;
- assert(bus);
-
- if (args[1]) {
- r = unit_name_mangle(args[1], UNIT_NAME_NOGLOB, &unit);
+ if (argv[1]) {
+ r = unit_name_mangle(argv[1], UNIT_NAME_NOGLOB, &unit);
if (r < 0)
return log_error_errno(r, "Failed to mangle unit name: %m");
@@ -1657,6 +1672,10 @@ static int list_dependencies(sd_bus *bus, char **args) {
pager_open_if_enabled();
+ r = acquire_bus(BUS_MANAGER, &bus);
+ if (r < 0)
+ return r;
+
puts(u);
return list_dependencies_one(bus, u, 0, &units, 0);
@@ -1872,12 +1891,11 @@ static void output_machines_list(struct machine_info *machine_infos, unsigned n)
printf("\n%u machines listed.\n", n);
}
-static int list_machines(sd_bus *bus, char **args) {
+static int list_machines(int argc, char *argv[], void *userdata) {
struct machine_info *machine_infos = NULL;
+ sd_bus *bus;
int r;
- assert(bus);
-
if (geteuid() != 0) {
log_error("Must be root.");
return -EPERM;
@@ -1885,7 +1903,11 @@ static int list_machines(sd_bus *bus, char **args) {
pager_open_if_enabled();
- r = get_machine_list(bus, &machine_infos, strv_skip_first(args));
+ r = acquire_bus(BUS_MANAGER, &bus);
+ if (r < 0)
+ return r;
+
+ r = get_machine_list(bus, &machine_infos, strv_skip(argv, 1));
if (r < 0)
return r;
@@ -1896,13 +1918,13 @@ static int list_machines(sd_bus *bus, char **args) {
return 0;
}
-static int get_default(sd_bus *bus, char **args) {
+static int get_default(int argc, char *argv[], void *userdata) {
_cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
_cleanup_free_ char *_path = NULL;
const char *path;
int r;
- if (!bus || avoid_bus()) {
+ if (install_client_side()) {
r = unit_file_get_default(arg_scope, arg_root, &_path);
if (r < 0)
return log_error_errno(r, "Failed to get default target: %m");
@@ -1910,6 +1932,11 @@ static int get_default(sd_bus *bus, char **args) {
} else {
_cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
+ sd_bus *bus;
+
+ r = acquire_bus(BUS_MANAGER, &bus);
+ if (r < 0)
+ return r;
r = sd_bus_call_method(
bus,
@@ -1920,10 +1947,8 @@ static int get_default(sd_bus *bus, char **args) {
&error,
&reply,
NULL);
- if (r < 0) {
- log_error("Failed to get default target: %s", bus_error_message(&error, -r));
- return r;
- }
+ if (r < 0)
+ return log_error_errno(r, "Failed to get default target: %s", bus_error_message(&error, r));
r = sd_bus_message_read(reply, "s", &path);
if (r < 0)
@@ -1949,17 +1974,21 @@ static void dump_unit_file_changes(const UnitFileChange *changes, unsigned n_cha
}
}
-static int set_default(sd_bus *bus, char **args) {
+static int set_default(int argc, char *argv[], void *userdata) {
_cleanup_free_ char *unit = NULL;
- UnitFileChange *changes = NULL;
- unsigned n_changes = 0;
int r;
- r = unit_name_mangle_with_suffix(args[1], UNIT_NAME_NOGLOB, ".target", &unit);
+ assert(argc >= 2);
+ assert(argv);
+
+ r = unit_name_mangle_with_suffix(argv[1], UNIT_NAME_NOGLOB, ".target", &unit);
if (r < 0)
return log_error_errno(r, "Failed to mangle unit name: %m");
- if (!bus || avoid_bus()) {
+ if (install_client_side()) {
+ UnitFileChange *changes = NULL;
+ unsigned n_changes = 0;
+
r = unit_file_set_default(arg_scope, arg_root, unit, true, &changes, &n_changes);
if (r < 0)
return log_error_errno(r, "Failed to set default target: %m");
@@ -1967,13 +1996,19 @@ static int set_default(sd_bus *bus, char **args) {
if (!arg_quiet)
dump_unit_file_changes(changes, n_changes);
+ unit_file_changes_free(changes, n_changes);
r = 0;
} else {
_cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
_cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
+ sd_bus *bus;
polkit_agent_open_if_enabled();
+ r = acquire_bus(BUS_MANAGER, &bus);
+ if (r < 0)
+ return r;
+
r = sd_bus_call_method(
bus,
"org.freedesktop.systemd1",
@@ -1983,10 +2018,8 @@ static int set_default(sd_bus *bus, char **args) {
&error,
&reply,
"sb", unit, 1);
- if (r < 0) {
- log_error("Failed to set default target: %s", bus_error_message(&error, -r));
- return r;
- }
+ if (r < 0)
+ return log_error_errno(r, "Failed to set default target: %s", bus_error_message(&error, r));
r = bus_deserialize_and_dump_unit_file_changes(reply, arg_quiet, NULL, NULL);
if (r < 0)
@@ -1994,13 +2027,11 @@ static int set_default(sd_bus *bus, char **args) {
/* Try to reload if enabled */
if (!arg_no_reload)
- r = daemon_reload(bus, args);
+ r = daemon_reload(argc, argv, userdata);
else
r = 0;
}
- unit_file_changes_free(changes, n_changes);
-
return r;
}
@@ -2085,17 +2116,24 @@ static bool output_show_job(struct job_info *job, char **patterns) {
return strv_fnmatch_or_empty(patterns, job->name, FNM_NOESCAPE);
}
-static int list_jobs(sd_bus *bus, char **args) {
+static int list_jobs(int argc, char *argv[], void *userdata) {
_cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
_cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
const char *name, *type, *state, *job_path, *unit_path;
_cleanup_free_ struct job_info *jobs = NULL;
size_t size = 0;
unsigned c = 0;
+ sd_bus *bus;
uint32_t id;
int r;
bool skipped = false;
+ pager_open_if_enabled();
+
+ r = acquire_bus(BUS_MANAGER, &bus);
+ if (r < 0)
+ return r;
+
r = sd_bus_call_method(
bus,
"org.freedesktop.systemd1",
@@ -2105,10 +2143,8 @@ static int list_jobs(sd_bus *bus, char **args) {
&error,
&reply,
NULL);
- if (r < 0) {
- log_error("Failed to list jobs: %s", bus_error_message(&error, r));
- return r;
- }
+ if (r < 0)
+ return log_error_errno(r, "Failed to list jobs: %s", bus_error_message(&error, r));
r = sd_bus_message_enter_container(reply, 'a', "(usssoo)");
if (r < 0)
@@ -2117,7 +2153,7 @@ static int list_jobs(sd_bus *bus, char **args) {
while ((r = sd_bus_message_read(reply, "(usssoo)", &id, &name, &type, &state, &job_path, &unit_path)) > 0) {
struct job_info job = { id, name, type, state };
- if (!output_show_job(&job, strv_skip_first(args))) {
+ if (!output_show_job(&job, strv_skip(argv, 1))) {
skipped = true;
continue;
}
@@ -2138,18 +2174,21 @@ static int list_jobs(sd_bus *bus, char **args) {
return r;
}
-static int cancel_job(sd_bus *bus, char **args) {
+static int cancel_job(int argc, char *argv[], void *userdata) {
+ sd_bus *bus;
char **name;
int r = 0;
- assert(args);
-
- if (strv_length(args) <= 1)
- return daemon_reload(bus, args);
+ if (argc <= 1)
+ return daemon_reload(argc, argv, userdata);
polkit_agent_open_if_enabled();
- STRV_FOREACH(name, args+1) {
+ r = acquire_bus(BUS_MANAGER, &bus);
+ if (r < 0)
+ return r;
+
+ STRV_FOREACH(name, strv_skip(argv, 1)) {
_cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
uint32_t id;
int q;
@@ -2168,7 +2207,7 @@ static int cancel_job(sd_bus *bus, char **args) {
NULL,
"u", id);
if (q < 0) {
- log_error("Failed to cancel job %"PRIu32": %s", id, bus_error_message(&error, q));
+ log_error_errno(q, "Failed to cancel job %"PRIu32": %s", id, bus_error_message(&error, q));
if (r == 0)
r = q;
}
@@ -2253,7 +2292,6 @@ static int unit_file_find_path(LookupPaths *lp, const char *unit_name, char **un
static int unit_find_paths(
sd_bus *bus,
const char *unit_name,
- bool avoid_bus_cache,
LookupPaths *lp,
char **fragment_path,
char ***dropin_paths) {
@@ -2274,7 +2312,7 @@ static int unit_find_paths(
assert(fragment_path);
assert(lp);
- if (!avoid_bus_cache && !unit_name_is_valid(unit_name, UNIT_NAME_TEMPLATE)) {
+ if (!install_client_side() && !unit_name_is_valid(unit_name, UNIT_NAME_TEMPLATE)) {
_cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
_cleanup_bus_message_unref_ sd_bus_message *unit_load_error = NULL;
_cleanup_free_ char *unit = NULL;
@@ -2471,10 +2509,8 @@ static int check_triggering_units(
"LoadState",
&error,
&state);
- if (r < 0) {
- log_error("Failed to get load state of %s: %s", n, bus_error_message(&error, r));
- return r;
- }
+ if (r < 0)
+ return log_error_errno(r, "Failed to get load state of %s: %s", n, bus_error_message(&error, r));
if (streq(state, "masked"))
return 0;
@@ -2487,10 +2523,8 @@ static int check_triggering_units(
"TriggeredBy",
&error,
&triggered_by);
- if (r < 0) {
- log_error("Failed to get triggered by array of %s: %s", n, bus_error_message(&error, r));
- return r;
- }
+ if (r < 0)
+ return log_error_errno(r, "Failed to get triggered by array of %s: %s", n, bus_error_message(&error, r));
STRV_FOREACH(i, triggered_by) {
r = check_one_unit(bus, *i, "active\0reloading\0", true);
@@ -2586,8 +2620,7 @@ static int start_unit_one(
verb = method_to_verb(method);
- log_error("Failed to %s %s: %s", verb, name, bus_error_message(error, r));
- return r;
+ return log_error_errno(r, "Failed to %s %s: %s", verb, name, bus_error_message(error, r));
}
r = sd_bus_message_read(reply, "o", &path);
@@ -2608,11 +2641,13 @@ static int start_unit_one(
}
static int expand_names(sd_bus *bus, char **names, const char* suffix, char ***ret) {
-
_cleanup_strv_free_ char **mangled = NULL, **globs = NULL;
char **name;
int r, i;
+ assert(bus);
+ assert(ret);
+
STRV_FOREACH(name, names) {
char *t;
@@ -2637,9 +2672,6 @@ static int expand_names(sd_bus *bus, char **names, const char* suffix, char ***r
_cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
_cleanup_free_ UnitInfo *unit_infos = NULL;
- if (!bus)
- return log_error_errno(EOPNOTSUPP, "Unit name globbing without bus is not implemented.");
-
r = get_unit_list(bus, NULL, globs, &unit_infos, 0, &reply);
if (r < 0)
return r;
@@ -2687,24 +2719,28 @@ static enum action verb_to_action(const char *verb) {
return _ACTION_INVALID;
}
-static int start_unit(sd_bus *bus, char **args) {
+static int start_unit(int argc, char *argv[], void *userdata) {
_cleanup_(bus_wait_for_jobs_freep) BusWaitForJobs *w = NULL;
const char *method, *mode, *one_name, *suffix = NULL;
_cleanup_strv_free_ char **names = NULL;
+ sd_bus *bus;
char **name;
int r = 0;
- assert(bus);
-
ask_password_agent_open_if_enabled();
polkit_agent_open_if_enabled();
+ r = acquire_bus(BUS_MANAGER, &bus);
+ if (r < 0)
+ return r;
+
if (arg_action == ACTION_SYSTEMCTL) {
enum action action;
- method = verb_to_method(args[0]);
- action = verb_to_action(args[0]);
- if (streq(args[0], "isolate")) {
+ method = verb_to_method(argv[0]);
+ action = verb_to_action(argv[0]);
+
+ if (streq(argv[0], "isolate")) {
mode = "isolate";
suffix = ".target";
} else
@@ -2724,9 +2760,9 @@ static int start_unit(sd_bus *bus, char **args) {
if (one_name)
names = strv_new(one_name, NULL);
else {
- r = expand_names(bus, args + 1, suffix, &names);
+ r = expand_names(bus, strv_skip(argv, 1), suffix, &names);
if (r < 0)
- log_error_errno(r, "Failed to expand names: %m");
+ return log_error_errno(r, "Failed to expand names: %m");
}
if (!arg_no_block) {
@@ -2761,18 +2797,55 @@ static int start_unit(sd_bus *bus, char **args) {
return r;
}
+static int logind_set_wall_message(void) {
+#ifdef HAVE_LOGIND
+ _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
+ sd_bus *bus;
+ _cleanup_free_ char *m = NULL;
+ int r;
+
+ r = acquire_bus(BUS_FULL, &bus);
+ if (r < 0)
+ return r;
+
+ m = strv_join(arg_wall, " ");
+ if (!m)
+ return log_oom();
+
+ r = sd_bus_call_method(
+ bus,
+ "org.freedesktop.login1",
+ "/org/freedesktop/login1",
+ "org.freedesktop.login1.Manager",
+ "SetWallMessage",
+ &error,
+ NULL,
+ "sb",
+ m,
+ !arg_no_wall);
+
+ if (r < 0)
+ return log_warning_errno(r, "Failed to set wall message, ignoring: %s", bus_error_message(&error, r));
+
+#endif
+ return 0;
+}
+
/* Ask systemd-logind, which might grant access to unprivileged users
* through PolicyKit */
-static int reboot_with_logind(sd_bus *bus, enum action a) {
+static int logind_reboot(enum action a) {
#ifdef HAVE_LOGIND
_cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
const char *method, *description;
+ sd_bus *bus;
int r;
- if (!bus)
- return -EIO;
-
polkit_agent_open_if_enabled();
+ (void) logind_set_wall_message();
+
+ r = acquire_bus(BUS_FULL, &bus);
+ if (r < 0)
+ return r;
switch (a) {
@@ -2805,33 +2878,6 @@ static int reboot_with_logind(sd_bus *bus, enum action a) {
return -EINVAL;
}
- if (!strv_isempty(arg_wall)) {
- _cleanup_free_ char *m;
-
- m = strv_join(arg_wall, " ");
- if (!m)
- return log_oom();
-
- r = sd_bus_call_method(
- bus,
- "org.freedesktop.login1",
- "/org/freedesktop/login1",
- "org.freedesktop.login1.Manager",
- "SetWallMessage",
- &error,
- NULL,
- "sb",
- m,
- !arg_no_wall);
-
- if (r < 0) {
- log_warning_errno(r, "Failed to set wall message, ignoring: %s",
- bus_error_message(&error, r));
- sd_bus_error_free(&error);
- }
- }
-
-
r = sd_bus_call_method(
bus,
"org.freedesktop.login1",
@@ -2842,27 +2888,25 @@ static int reboot_with_logind(sd_bus *bus, enum action a) {
NULL,
"b", arg_ask_password);
if (r < 0)
- log_error("Failed to %s via logind: %s", description, bus_error_message(&error, r));
+ return log_error_errno(r, "Failed to %s via logind: %s", description, bus_error_message(&error, r));
- return r;
+ return 0;
#else
return -ENOSYS;
#endif
}
-static int check_inhibitors(sd_bus *bus, enum action a) {
+static int logind_check_inhibitors(enum action a) {
#ifdef HAVE_LOGIND
_cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
_cleanup_strv_free_ char **sessions = NULL;
const char *what, *who, *why, *mode;
uint32_t uid, pid;
+ sd_bus *bus;
unsigned c = 0;
char **s;
int r;
- if (!bus)
- return 0;
-
if (arg_ignore_inhibitors || arg_force > 0)
return 0;
@@ -2875,6 +2919,10 @@ static int check_inhibitors(sd_bus *bus, enum action a) {
if (!on_tty())
return 0;
+ r = acquire_bus(BUS_FULL, &bus);
+ if (r < 0)
+ return r;
+
r = sd_bus_call_method(
bus,
"org.freedesktop.login1",
@@ -2964,10 +3012,36 @@ static int check_inhibitors(sd_bus *bus, enum action a) {
#endif
}
-static int prepare_firmware_setup(sd_bus *bus) {
+static int logind_prepare_firmware_setup(void) {
#ifdef HAVE_LOGIND
_cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
+ sd_bus *bus;
+ int r;
+
+ r = acquire_bus(BUS_FULL, &bus);
+ if (r < 0)
+ return r;
+
+ r = sd_bus_call_method(
+ bus,
+ "org.freedesktop.login1",
+ "/org/freedesktop/login1",
+ "org.freedesktop.login1.Manager",
+ "SetRebootToFirmwareSetup",
+ &error,
+ NULL,
+ "b", true);
+ if (r < 0)
+ return log_error_errno(r, "Cannot indicate to EFI to boot into setup mode: %s", bus_error_message(&error, r));
+
+ return 0;
+#else
+ log_error("Cannot remotely indicate to EFI to boot into setup mode.");
+ return -ENOSYS;
#endif
+}
+
+static int prepare_firmware_setup(void) {
int r;
if (!arg_firmware_setup)
@@ -2982,38 +3056,42 @@ static int prepare_firmware_setup(sd_bus *bus) {
return r;
}
-#ifdef HAVE_LOGIND
+ return logind_prepare_firmware_setup();
+}
+
+static int set_exit_code(uint8_t code) {
+ _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
+ sd_bus *bus;
+ int r;
+
+ r = acquire_bus(BUS_MANAGER, &bus);
+ if (r < 0)
+ return r;
+
r = sd_bus_call_method(
bus,
- "org.freedesktop.login1",
- "/org/freedesktop/login1",
- "org.freedesktop.login1.Manager",
- "SetRebootToFirmwareSetup",
+ "org.freedesktop.systemd1",
+ "/org/freedesktop/systemd1",
+ "org.freedesktop.systemd1.Manager",
+ "SetExitCode",
&error,
NULL,
- "b", true);
- if (r < 0) {
- log_error("Cannot indicate to EFI to boot into setup mode: %s", bus_error_message(&error, r));
- return r;
- }
+ "y", code);
+ if (r < 0)
+ return log_error_errno(r, "Failed to execute operation: %s", bus_error_message(&error, r));
return 0;
-#else
- log_error("Cannot remotely indicate to EFI to boot into setup mode.");
- return -EINVAL;
-#endif
}
-static int start_special(sd_bus *bus, char **args) {
- _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
+static int start_special(int argc, char *argv[], void *userdata) {
enum action a;
int r;
- assert(args);
+ assert(argv);
- a = verb_to_action(args[0]);
+ a = verb_to_action(argv[0]);
- r = check_inhibitors(bus, a);
+ r = logind_check_inhibitors(a);
if (r < 0)
return r;
@@ -3022,39 +3100,29 @@ static int start_special(sd_bus *bus, char **args) {
return -EPERM;
}
- r = prepare_firmware_setup(bus);
+ r = prepare_firmware_setup();
if (r < 0)
return r;
- if (a == ACTION_REBOOT && args[1]) {
- r = update_reboot_param_file(args[1]);
+ if (a == ACTION_REBOOT && argc > 1) {
+ r = update_reboot_param_file(argv[1]);
if (r < 0)
return r;
- } else if (a == ACTION_EXIT && strv_length(args) > 1) {
- /* If the exit code is not given on the command line, don't
- * reset it to zero: just keep it as it might have been set
- * previously. */
+
+ } else if (a == ACTION_EXIT && argc > 1) {
uint8_t code = 0;
- r = safe_atou8(args[1], &code);
- if (r < 0) {
- log_error("Invalid exit code.");
- return -EINVAL;
- }
+ /* If the exit code is not given on the command line,
+ * don't reset it to zero: just keep it as it might
+ * have been set previously. */
- r = sd_bus_call_method(
- bus,
- "org.freedesktop.systemd1",
- "/org/freedesktop/systemd1",
- "org.freedesktop.systemd1.Manager",
- "SetExitCode",
- &error,
- NULL,
- "y", code);
- if (r < 0) {
- log_error("Failed to execute operation: %s", bus_error_message(&error, r));
+ r = safe_atou8(argv[1], &code);
+ if (r < 0)
+ return log_error_errno(r, "Invalid exit code.");
+
+ r = set_exit_code(code);
+ if (r < 0)
return r;
- }
}
if (arg_force >= 2 &&
@@ -3071,39 +3139,37 @@ static int start_special(sd_bus *bus, char **args) {
ACTION_REBOOT,
ACTION_KEXEC,
ACTION_EXIT))
- return daemon_reload(bus, args);
+ return daemon_reload(argc, argv, userdata);
- /* first try logind, to allow authentication with polkit */
- if (geteuid() != 0 &&
- IN_SET(a,
+ /* First try logind, to allow authentication with polkit */
+ if (IN_SET(a,
ACTION_POWEROFF,
ACTION_REBOOT,
ACTION_SUSPEND,
ACTION_HIBERNATE,
ACTION_HYBRID_SLEEP)) {
- r = reboot_with_logind(bus, a);
+ r = logind_reboot(a);
if (r >= 0)
return r;
if (IN_SET(r, -EOPNOTSUPP, -EINPROGRESS))
/* requested operation is not supported or already in progress */
return r;
- /* on all other errors, try low-level operation */
- }
- r = start_unit(bus, args);
- if (r == EXIT_SUCCESS)
- warn_wall(a);
+ /* On all other errors, try low-level operation */
+ }
- return r;
+ return start_unit(argc, argv, userdata);
}
-static int check_unit_generic(sd_bus *bus, int code, const char *good_states, char **args) {
+static int check_unit_generic(int code, const char *good_states, char **args) {
_cleanup_strv_free_ char **names = NULL;
+ sd_bus *bus;
char **name;
int r;
- assert(bus);
- assert(args);
+ r = acquire_bus(BUS_MANAGER, &bus);
+ if (r < 0)
+ return r;
r = expand_names(bus, args, NULL, &names);
if (r < 0)
@@ -3122,25 +3188,27 @@ static int check_unit_generic(sd_bus *bus, int code, const char *good_states, ch
return r;
}
-static int check_unit_active(sd_bus *bus, char **args) {
+static int check_unit_active(int argc, char *argv[], void *userdata) {
/* According to LSB: 3, "program is not running" */
- return check_unit_generic(bus, 3, "active\0reloading\0", args + 1);
+ return check_unit_generic(3, "active\0reloading\0", strv_skip(argv, 1));
}
-static int check_unit_failed(sd_bus *bus, char **args) {
- return check_unit_generic(bus, 1, "failed\0", args + 1);
+static int check_unit_failed(int argc, char *argv[], void *userdata) {
+ return check_unit_generic(1, "failed\0", strv_skip(argv, 1));
}
-static int kill_unit(sd_bus *bus, char **args) {
+static int kill_unit(int argc, char *argv[], void *userdata) {
_cleanup_strv_free_ char **names = NULL;
char *kill_who = NULL, **name;
+ sd_bus *bus;
int r, q;
- assert(bus);
- assert(args);
-
polkit_agent_open_if_enabled();
+ r = acquire_bus(BUS_MANAGER, &bus);
+ if (r < 0)
+ return r;
+
if (!arg_kill_who)
arg_kill_who = "all";
@@ -3148,9 +3216,9 @@ static int kill_unit(sd_bus *bus, char **args) {
if (streq(arg_job_mode, "fail"))
kill_who = strjoina(arg_kill_who, "-fail", NULL);
- r = expand_names(bus, args + 1, NULL, &names);
+ r = expand_names(bus, strv_skip(argv, 1), NULL, &names);
if (r < 0)
- log_error_errno(r, "Failed to expand names: %m");
+ return log_error_errno(r, "Failed to expand names: %m");
STRV_FOREACH(name, names) {
_cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
@@ -3165,7 +3233,7 @@ static int kill_unit(sd_bus *bus, char **args) {
NULL,
"ssi", *names, kill_who ? kill_who : arg_kill_who, arg_signal);
if (q < 0) {
- log_error("Failed to kill unit %s: %s", *names, bus_error_message(&error, q));
+ log_error_errno(q, "Failed to kill unit %s: %s", *names, bus_error_message(&error, q));
if (r == 0)
r = q;
}
@@ -3456,7 +3524,7 @@ static void print_status_info(
printf("Condition: start %scondition failed%s at %s%s%s\n",
ansi_highlight_yellow(), ansi_normal(),
- s2, s1 ? "; " : "", s1 ? s1 : "");
+ s2, s1 ? "; " : "", strempty(s1));
if (i->failed_condition_trigger)
printf(" none of the trigger conditions were met\n");
else if (i->failed_condition)
@@ -3472,7 +3540,7 @@ static void print_status_info(
printf(" Assert: start %sassertion failed%s at %s%s%s\n",
ansi_highlight_red(), ansi_normal(),
- s2, s1 ? "; " : "", s1 ? s1 : "");
+ s2, s1 ? "; " : "", strempty(s1));
if (i->failed_assert_trigger)
printf(" none of the trigger assertions were met\n");
else if (i->failed_assert)
@@ -3861,13 +3929,13 @@ static int status_property(const char *name, sd_bus_message *m, UnitStatusInfo *
info->name = strdup(name);
if (!info->name)
- log_oom();
+ return log_oom();
LIST_PREPEND(exec, i->exec, info);
info = new0(ExecStatusInfo, 1);
if (!info)
- log_oom();
+ return log_oom();
}
if (r < 0)
@@ -4439,10 +4507,8 @@ static int get_unit_dbus_path_by_pid(
&error,
&reply,
"u", pid);
- if (r < 0) {
- log_error("Failed to get unit for PID %"PRIu32": %s", pid, bus_error_message(&error, r));
- return r;
- }
+ if (r < 0)
+ return log_error_errno(r, "Failed to get unit for PID %"PRIu32": %s", pid, bus_error_message(&error, r));
r = sd_bus_message_read(reply, "o", &u);
if (r < 0)
@@ -4551,16 +4617,22 @@ static int show_system_status(sd_bus *bus) {
return 0;
}
-static int show(sd_bus *bus, char **args) {
- bool show_properties, show_status, new_line = false;
+static int show(int argc, char *argv[], void *userdata) {
+ bool show_properties, show_status, show_help, new_line = false;
bool ellipsized = false;
int r, ret = 0;
+ sd_bus *bus;
- assert(bus);
- assert(args);
+ assert(argv);
- show_properties = streq(args[0], "show");
- show_status = streq(args[0], "status");
+ show_properties = streq(argv[0], "show");
+ show_status = streq(argv[0], "status");
+ show_help = streq(argv[0], "help");
+
+ if (show_help && argc <= 1) {
+ log_error("This command expects one or more unit names. Did you mean --help?");
+ return -EINVAL;
+ }
if (show_properties)
pager_open_if_enabled();
@@ -4571,24 +4643,27 @@ static int show(sd_bus *bus, char **args) {
* be split up into many files. */
setrlimit_closest(RLIMIT_NOFILE, &RLIMIT_MAKE_CONST(16384));
- /* If no argument is specified inspect the manager itself */
+ r = acquire_bus(BUS_MANAGER, &bus);
+ if (r < 0)
+ return r;
- if (show_properties && strv_length(args) <= 1)
- return show_one(args[0], bus, "/org/freedesktop/systemd1", show_properties, &new_line, &ellipsized);
+ /* If no argument is specified inspect the manager itself */
+ if (show_properties && argc <= 1)
+ return show_one(argv[0], bus, "/org/freedesktop/systemd1", show_properties, &new_line, &ellipsized);
- if (show_status && strv_length(args) <= 1) {
+ if (show_status && argc <= 1) {
pager_open_if_enabled();
show_system_status(bus);
new_line = true;
if (arg_all)
- ret = show_all(args[0], bus, false, &new_line, &ellipsized);
+ ret = show_all(argv[0], bus, false, &new_line, &ellipsized);
} else {
_cleanup_free_ char **patterns = NULL;
char **name;
- STRV_FOREACH(name, args + 1) {
+ STRV_FOREACH(name, strv_skip(argv, 1)) {
_cleanup_free_ char *unit = NULL;
uint32_t id;
@@ -4611,8 +4686,7 @@ static int show(sd_bus *bus, char **args) {
}
}
- r = show_one(args[0], bus, unit, show_properties,
- &new_line, &ellipsized);
+ r = show_one(argv[0], bus, unit, show_properties, &new_line, &ellipsized);
if (r < 0)
return r;
else if (r > 0 && ret == 0)
@@ -4624,7 +4698,7 @@ static int show(sd_bus *bus, char **args) {
r = expand_names(bus, patterns, NULL, &names);
if (r < 0)
- log_error_errno(r, "Failed to expand names: %m");
+ return log_error_errno(r, "Failed to expand names: %m");
STRV_FOREACH(name, names) {
_cleanup_free_ char *unit;
@@ -4633,8 +4707,7 @@ static int show(sd_bus *bus, char **args) {
if (!unit)
return log_oom();
- r = show_one(args[0], bus, unit, show_properties,
- &new_line, &ellipsized);
+ r = show_one(argv[0], bus, unit, show_properties, &new_line, &ellipsized);
if (r < 0)
return r;
else if (r > 0 && ret == 0)
@@ -4694,19 +4767,18 @@ static int cat_file(const char *filename, bool newline) {
return copy_bytes(fd, STDOUT_FILENO, (uint64_t) -1, false);
}
-static int cat(sd_bus *bus, char **args) {
+static int cat(int argc, char *argv[], void *userdata) {
_cleanup_free_ char *user_home = NULL;
_cleanup_free_ char *user_runtime = NULL;
_cleanup_lookup_paths_free_ LookupPaths lp = {};
_cleanup_strv_free_ char **names = NULL;
char **name;
- bool first = true, avoid_bus_cache;
+ sd_bus *bus;
+ bool first = true;
int r;
- assert(args);
-
if (arg_transport != BUS_TRANSPORT_LOCAL) {
- log_error("Cannot remotely cat units");
+ log_error("Cannot remotely cat units.");
return -EINVAL;
}
@@ -4714,11 +4786,13 @@ static int cat(sd_bus *bus, char **args) {
if (r < 0)
return r;
- r = expand_names(bus, args + 1, NULL, &names);
+ r = acquire_bus(BUS_MANAGER, &bus);
if (r < 0)
- return log_error_errno(r, "Failed to expand names: %m");
+ return r;
- avoid_bus_cache = !bus || avoid_bus();
+ r = expand_names(bus, strv_skip(argv, 1), NULL, &names);
+ if (r < 0)
+ return log_error_errno(r, "Failed to expand names: %m");
pager_open_if_enabled();
@@ -4727,7 +4801,7 @@ static int cat(sd_bus *bus, char **args) {
_cleanup_strv_free_ char **dropin_paths = NULL;
char **path;
- r = unit_find_paths(bus, *name, avoid_bus_cache, &lp, &fragment_path, &dropin_paths);
+ r = unit_find_paths(bus, *name, &lp, &fragment_path, &dropin_paths);
if (r < 0)
return r;
else if (r == 0)
@@ -4754,15 +4828,20 @@ static int cat(sd_bus *bus, char **args) {
return 0;
}
-static int set_property(sd_bus *bus, char **args) {
+static int set_property(int argc, char *argv[], void *userdata) {
_cleanup_bus_message_unref_ sd_bus_message *m = NULL;
_cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
_cleanup_free_ char *n = NULL;
+ sd_bus *bus;
char **i;
int r;
polkit_agent_open_if_enabled();
+ r = acquire_bus(BUS_MANAGER, &bus);
+ if (r < 0)
+ return r;
+
r = sd_bus_message_new_method_call(
bus,
&m,
@@ -4773,7 +4852,7 @@ static int set_property(sd_bus *bus, char **args) {
if (r < 0)
return bus_log_create_error(r);
- r = unit_name_mangle(args[1], UNIT_NAME_NOGLOB, &n);
+ r = unit_name_mangle(argv[1], UNIT_NAME_NOGLOB, &n);
if (r < 0)
return log_error_errno(r, "Failed to mangle unit name: %m");
@@ -4785,7 +4864,7 @@ static int set_property(sd_bus *bus, char **args) {
if (r < 0)
return bus_log_create_error(r);
- STRV_FOREACH(i, args + 2) {
+ STRV_FOREACH(i, strv_skip(argv, 2)) {
r = sd_bus_message_open_container(m, SD_BUS_TYPE_STRUCT, "sv");
if (r < 0)
return bus_log_create_error(r);
@@ -4804,25 +4883,24 @@ static int set_property(sd_bus *bus, char **args) {
return bus_log_create_error(r);
r = sd_bus_call(bus, m, 0, &error, NULL);
- if (r < 0) {
- log_error("Failed to set unit properties on %s: %s", n, bus_error_message(&error, r));
- return r;
- }
+ if (r < 0)
+ return log_error_errno(r, "Failed to set unit properties on %s: %s", n, bus_error_message(&error, r));
return 0;
}
-static int snapshot(sd_bus *bus, char **args) {
+static int snapshot(int argc, char *argv[], void *userdata) {
_cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
_cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
_cleanup_free_ char *n = NULL, *id = NULL;
const char *path;
+ sd_bus *bus;
int r;
polkit_agent_open_if_enabled();
- if (strv_length(args) > 1) {
- r = unit_name_mangle_with_suffix(args[1], UNIT_NAME_NOGLOB, ".snapshot", &n);
+ if (argc > 1) {
+ r = unit_name_mangle_with_suffix(argv[1], UNIT_NAME_NOGLOB, ".snapshot", &n);
if (r < 0)
return log_error_errno(r, "Failed to generate unit name: %m");
} else {
@@ -4831,6 +4909,10 @@ static int snapshot(sd_bus *bus, char **args) {
return log_oom();
}
+ r = acquire_bus(BUS_MANAGER, &bus);
+ if (r < 0)
+ return r;
+
r = sd_bus_call_method(
bus,
"org.freedesktop.systemd1",
@@ -4840,10 +4922,8 @@ static int snapshot(sd_bus *bus, char **args) {
&error,
&reply,
"sb", n, false);
- if (r < 0) {
- log_error("Failed to create snapshot: %s", bus_error_message(&error, r));
- return r;
- }
+ if (r < 0)
+ return log_error_errno(r, "Failed to create snapshot: %s", bus_error_message(&error, r));
r = sd_bus_message_read(reply, "o", &path);
if (r < 0)
@@ -4857,10 +4937,8 @@ static int snapshot(sd_bus *bus, char **args) {
"Id",
&error,
&id);
- if (r < 0) {
- log_error("Failed to get ID of snapshot: %s", bus_error_message(&error, r));
- return r;
- }
+ if (r < 0)
+ return log_error_errno(r, "Failed to get ID of snapshot: %s", bus_error_message(&error, r));
if (!arg_quiet)
puts(id);
@@ -4868,18 +4946,21 @@ static int snapshot(sd_bus *bus, char **args) {
return 0;
}
-static int delete_snapshot(sd_bus *bus, char **args) {
+static int delete_snapshot(int argc, char *argv[], void *userdata) {
_cleanup_strv_free_ char **names = NULL;
+ sd_bus *bus;
char **name;
int r;
- assert(args);
-
polkit_agent_open_if_enabled();
- r = expand_names(bus, args + 1, ".snapshot", &names);
+ r = acquire_bus(BUS_MANAGER, &bus);
if (r < 0)
- log_error_errno(r, "Failed to expand names: %m");
+ return r;
+
+ r = expand_names(bus, strv_skip(argv, 1), ".snapshot", &names);
+ if (r < 0)
+ return log_error_errno(r, "Failed to expand names: %m");
STRV_FOREACH(name, names) {
_cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
@@ -4895,7 +4976,7 @@ static int delete_snapshot(sd_bus *bus, char **args) {
NULL,
"s", *name);
if (q < 0) {
- log_error("Failed to remove snapshot %s: %s", *name, bus_error_message(&error, q));
+ log_error_errno(q, "Failed to remove snapshot %s: %s", *name, bus_error_message(&error, q));
if (r == 0)
r = q;
}
@@ -4904,13 +4985,18 @@ static int delete_snapshot(sd_bus *bus, char **args) {
return r;
}
-static int daemon_reload(sd_bus *bus, char **args) {
+static int daemon_reload(int argc, char *argv[], void *userdata) {
_cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
const char *method;
+ sd_bus *bus;
int r;
polkit_agent_open_if_enabled();
+ r = acquire_bus(BUS_MANAGER, &bus);
+ if (r < 0)
+ return r;
+
if (arg_action == ACTION_RELOAD)
method = "Reload";
else if (arg_action == ACTION_REEXEC)
@@ -4919,15 +5005,15 @@ static int daemon_reload(sd_bus *bus, char **args) {
assert(arg_action == ACTION_SYSTEMCTL);
method =
- streq(args[0], "clear-jobs") ||
- streq(args[0], "cancel") ? "ClearJobs" :
- streq(args[0], "daemon-reexec") ? "Reexecute" :
- streq(args[0], "reset-failed") ? "ResetFailed" :
- streq(args[0], "halt") ? "Halt" :
- streq(args[0], "poweroff") ? "PowerOff" :
- streq(args[0], "reboot") ? "Reboot" :
- streq(args[0], "kexec") ? "KExec" :
- streq(args[0], "exit") ? "Exit" :
+ streq(argv[0], "clear-jobs") ||
+ streq(argv[0], "cancel") ? "ClearJobs" :
+ streq(argv[0], "daemon-reexec") ? "Reexecute" :
+ streq(argv[0], "reset-failed") ? "ResetFailed" :
+ streq(argv[0], "halt") ? "Halt" :
+ streq(argv[0], "poweroff") ? "PowerOff" :
+ streq(argv[0], "reboot") ? "Reboot" :
+ streq(argv[0], "kexec") ? "KExec" :
+ streq(argv[0], "exit") ? "Exit" :
/* "daemon-reload" */ "Reload";
}
@@ -4949,24 +5035,29 @@ static int daemon_reload(sd_bus *bus, char **args) {
* reply */
r = 0;
else if (r < 0)
- log_error("Failed to execute operation: %s", bus_error_message(&error, r));
+ return log_error_errno(r, "Failed to execute operation: %s", bus_error_message(&error, r));
return r < 0 ? r : 0;
}
-static int reset_failed(sd_bus *bus, char **args) {
+static int reset_failed(int argc, char *argv[], void *userdata) {
_cleanup_strv_free_ char **names = NULL;
+ sd_bus *bus;
char **name;
int r, q;
- if (strv_length(args) <= 1)
- return daemon_reload(bus, args);
+ if (argc <= 1)
+ return daemon_reload(argc, argv, userdata);
polkit_agent_open_if_enabled();
- r = expand_names(bus, args + 1, NULL, &names);
+ r = acquire_bus(BUS_MANAGER, &bus);
if (r < 0)
- log_error_errno(r, "Failed to expand names: %m");
+ return r;
+
+ r = expand_names(bus, strv_skip(argv, 1), NULL, &names);
+ if (r < 0)
+ return log_error_errno(r, "Failed to expand names: %m");
STRV_FOREACH(name, names) {
_cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
@@ -4981,7 +5072,7 @@ static int reset_failed(sd_bus *bus, char **args) {
NULL,
"s", *name);
if (q < 0) {
- log_error("Failed to reset failed state of unit %s: %s", *name, bus_error_message(&error, q));
+ log_error_errno(q, "Failed to reset failed state of unit %s: %s", *name, bus_error_message(&error, q));
if (r == 0)
r = q;
}
@@ -4990,14 +5081,19 @@ static int reset_failed(sd_bus *bus, char **args) {
return r;
}
-static int show_environment(sd_bus *bus, char **args) {
+static int show_environment(int argc, char *argv[], void *userdata) {
_cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
_cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
const char *text;
+ sd_bus *bus;
int r;
pager_open_if_enabled();
+ r = acquire_bus(BUS_MANAGER, &bus);
+ if (r < 0)
+ return r;
+
r = sd_bus_get_property(
bus,
"org.freedesktop.systemd1",
@@ -5007,10 +5103,8 @@ static int show_environment(sd_bus *bus, char **args) {
&error,
&reply,
"as");
- if (r < 0) {
- log_error("Failed to get environment: %s", bus_error_message(&error, r));
- return r;
- }
+ if (r < 0)
+ return log_error_errno(r, "Failed to get environment: %s", bus_error_message(&error, r));
r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "s");
if (r < 0)
@@ -5028,23 +5122,27 @@ static int show_environment(sd_bus *bus, char **args) {
return 0;
}
-static int switch_root(sd_bus *bus, char **args) {
+static int switch_root(int argc, char *argv[], void *userdata) {
_cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
_cleanup_free_ char *cmdline_init = NULL;
const char *root, *init;
- unsigned l;
+ sd_bus *bus;
int r;
- l = strv_length(args);
- if (l < 2 || l > 3) {
+ if (arg_transport != BUS_TRANSPORT_LOCAL) {
+ log_error("Cannot switch root remotely.");
+ return -EINVAL;
+ }
+
+ if (argc < 2 || argc > 3) {
log_error("Wrong number of arguments.");
return -EINVAL;
}
- root = args[1];
+ root = argv[1];
- if (l >= 3)
- init = args[2];
+ if (argc >= 3)
+ init = argv[2];
else {
r = parse_env_file("/proc/cmdline", WHITESPACE,
"init", &cmdline_init,
@@ -5070,6 +5168,10 @@ static int switch_root(sd_bus *bus, char **args) {
init = NULL;
}
+ r = acquire_bus(BUS_MANAGER, &bus);
+ if (r < 0)
+ return r;
+
log_debug("Switching root - root: %s; init: %s", root, strna(init));
r = sd_bus_call_method(
@@ -5081,26 +5183,29 @@ static int switch_root(sd_bus *bus, char **args) {
&error,
NULL,
"ss", root, init);
- if (r < 0) {
- log_error("Failed to switch root: %s", bus_error_message(&error, r));
- return r;
- }
+ if (r < 0)
+ return log_error_errno(r, "Failed to switch root: %s", bus_error_message(&error, r));
return 0;
}
-static int set_environment(sd_bus *bus, char **args) {
+static int set_environment(int argc, char *argv[], void *userdata) {
_cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
_cleanup_bus_message_unref_ sd_bus_message *m = NULL;
const char *method;
+ sd_bus *bus;
int r;
- assert(bus);
- assert(args);
+ assert(argc > 1);
+ assert(argv);
polkit_agent_open_if_enabled();
- method = streq(args[0], "set-environment")
+ r = acquire_bus(BUS_MANAGER, &bus);
+ if (r < 0)
+ return r;
+
+ method = streq(argv[0], "set-environment")
? "SetEnvironment"
: "UnsetEnvironment";
@@ -5114,29 +5219,29 @@ static int set_environment(sd_bus *bus, char **args) {
if (r < 0)
return bus_log_create_error(r);
- r = sd_bus_message_append_strv(m, args + 1);
+ r = sd_bus_message_append_strv(m, strv_skip(argv, 1));
if (r < 0)
return bus_log_create_error(r);
r = sd_bus_call(bus, m, 0, &error, NULL);
- if (r < 0) {
- log_error("Failed to set environment: %s", bus_error_message(&error, r));
- return r;
- }
+ if (r < 0)
+ return log_error_errno(r, "Failed to set environment: %s", bus_error_message(&error, r));
return 0;
}
-static int import_environment(sd_bus *bus, char **args) {
+static int import_environment(int argc, char *argv[], void *userdata) {
_cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
_cleanup_bus_message_unref_ sd_bus_message *m = NULL;
+ sd_bus *bus;
int r;
- assert(bus);
- assert(args);
-
polkit_agent_open_if_enabled();
+ r = acquire_bus(BUS_MANAGER, &bus);
+ if (r < 0)
+ return r;
+
r = sd_bus_message_new_method_call(
bus,
&m,
@@ -5147,7 +5252,7 @@ static int import_environment(sd_bus *bus, char **args) {
if (r < 0)
return bus_log_create_error(r);
- if (strv_isempty(args + 1))
+ if (argc < 2)
r = sd_bus_message_append_strv(m, environ);
else {
char **a, **b;
@@ -5156,7 +5261,7 @@ static int import_environment(sd_bus *bus, char **args) {
if (r < 0)
return bus_log_create_error(r);
- STRV_FOREACH(a, args + 1) {
+ STRV_FOREACH(a, strv_skip(argv, 1)) {
if (!env_name_is_valid(*a)) {
log_error("Not a valid environment variable name: %s", *a);
@@ -5184,10 +5289,8 @@ static int import_environment(sd_bus *bus, char **args) {
return bus_log_create_error(r);
r = sd_bus_call(bus, m, 0, &error, NULL);
- if (r < 0) {
- log_error("Failed to import environment: %s", bus_error_message(&error, r));
- return r;
- }
+ if (r < 0)
+ return log_error_errno(r, "Failed to import environment: %s", bus_error_message(&error, r));
return 0;
}
@@ -5290,13 +5393,13 @@ static int enable_sysv_units(const char *verb, char **args) {
(void) reset_signal_mask();
execv(argv[0], (char**) argv);
- log_error("Failed to execute %s: %m", argv[0]);
+ log_error_errno(r, "Failed to execute %s: %m", argv[0]);
_exit(EXIT_FAILURE);
}
j = wait_for_terminate(pid, &status);
if (j < 0) {
- log_error_errno(r, "Failed to wait for child: %m");
+ log_error_errno(j, "Failed to wait for child: %m");
return j;
}
@@ -5366,18 +5469,18 @@ static int mangle_names(char **original_names, char ***mangled_names) {
return 0;
}
-static int enable_unit(sd_bus *bus, char **args) {
+static int enable_unit(int argc, char *argv[], void *userdata) {
_cleanup_strv_free_ char **names = NULL;
- const char *verb = args[0];
+ const char *verb = argv[0];
UnitFileChange *changes = NULL;
unsigned n_changes = 0;
int carries_install_info = -1;
int r;
- if (!args[1])
+ if (!argv[1])
return 0;
- r = mangle_names(args+1, &names);
+ r = mangle_names(strv_skip(argv, 1), &names);
if (r < 0)
return r;
@@ -5390,7 +5493,7 @@ static int enable_unit(sd_bus *bus, char **args) {
if (strv_isempty(names))
return 0;
- if (!bus || avoid_bus()) {
+ if (install_client_side()) {
if (streq(verb, "enable")) {
r = unit_file_enable(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
carries_install_info = r;
@@ -5426,9 +5529,14 @@ static int enable_unit(sd_bus *bus, char **args) {
int expect_carries_install_info = false;
bool send_force = true, send_preset_mode = false;
const char *method;
+ sd_bus *bus;
polkit_agent_open_if_enabled();
+ r = acquire_bus(BUS_MANAGER, &bus);
+ if (r < 0)
+ return r;
+
if (streq(verb, "enable")) {
method = "EnableUnitFiles";
expect_carries_install_info = true;
@@ -5488,10 +5596,8 @@ static int enable_unit(sd_bus *bus, char **args) {
}
r = sd_bus_call(bus, m, 0, &error, &reply);
- if (r < 0) {
- log_error("Failed to execute operation: %s", bus_error_message(&error, r));
- return r;
- }
+ if (r < 0)
+ return log_error_errno(r, "Failed to execute operation: %s", bus_error_message(&error, r));
if (expect_carries_install_info) {
r = sd_bus_message_read(reply, "b", &carries_install_info);
@@ -5505,7 +5611,7 @@ static int enable_unit(sd_bus *bus, char **args) {
/* Try to reload if enabled */
if (!arg_no_reload)
- r = daemon_reload(bus, args);
+ r = daemon_reload(argc, argv, userdata);
else
r = 0;
}
@@ -5521,16 +5627,21 @@ static int enable_unit(sd_bus *bus, char **args) {
"3) A unit may be started when needed via activation (socket, path, timer,\n"
" D-Bus, udev, scripted systemctl call, ...).\n");
- if (arg_now && n_changes > 0 && STR_IN_SET(args[0], "enable", "disable", "mask")) {
+ if (arg_now && n_changes > 0 && STR_IN_SET(argv[0], "enable", "disable", "mask")) {
char *new_args[n_changes + 2];
+ sd_bus *bus;
unsigned i;
- new_args[0] = streq(args[0], "enable") ? (char *)"start" : (char *)"stop";
+ r = acquire_bus(BUS_MANAGER, &bus);
+ if (r < 0)
+ return r;
+
+ new_args[0] = (char*) (streq(argv[0], "enable") ? "start" : "stop");
for (i = 0; i < n_changes; i++)
new_args[i + 1] = basename(changes[i].path);
new_args[i + 1] = NULL;
- r = start_unit(bus, new_args);
+ r = start_unit(strv_length(new_args), new_args, userdata);
}
finish:
@@ -5539,21 +5650,21 @@ finish:
return r;
}
-static int add_dependency(sd_bus *bus, char **args) {
+static int add_dependency(int argc, char *argv[], void *userdata) {
_cleanup_strv_free_ char **names = NULL;
_cleanup_free_ char *target = NULL;
- const char *verb = args[0];
+ const char *verb = argv[0];
UnitDependency dep;
int r = 0;
- if (!args[1])
+ if (!argv[1])
return 0;
- r = unit_name_mangle_with_suffix(args[1], UNIT_NAME_NOGLOB, ".target", &target);
+ r = unit_name_mangle_with_suffix(argv[1], UNIT_NAME_NOGLOB, ".target", &target);
if (r < 0)
return log_error_errno(r, "Failed to mangle unit name: %m");
- r = mangle_names(args+2, &names);
+ r = mangle_names(strv_skip(argv, 2), &names);
if (r < 0)
return r;
@@ -5564,7 +5675,7 @@ static int add_dependency(sd_bus *bus, char **args) {
else
assert_not_reached("Unknown verb");
- if (!bus || avoid_bus()) {
+ if (install_client_side()) {
UnitFileChange *changes = NULL;
unsigned n_changes = 0;
@@ -5581,9 +5692,14 @@ static int add_dependency(sd_bus *bus, char **args) {
} else {
_cleanup_bus_message_unref_ sd_bus_message *reply = NULL, *m = NULL;
_cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
+ sd_bus *bus;
polkit_agent_open_if_enabled();
+ r = acquire_bus(BUS_MANAGER, &bus);
+ if (r < 0)
+ return r;
+
r = sd_bus_message_new_method_call(
bus,
&m,
@@ -5603,17 +5719,15 @@ static int add_dependency(sd_bus *bus, char **args) {
return bus_log_create_error(r);
r = sd_bus_call(bus, m, 0, &error, &reply);
- if (r < 0) {
- log_error("Failed to execute operation: %s", bus_error_message(&error, r));
- return r;
- }
+ if (r < 0)
+ return log_error_errno(r, "Failed to execute operation: %s", bus_error_message(&error, r));
r = bus_deserialize_and_dump_unit_file_changes(reply, arg_quiet, NULL, NULL);
if (r < 0)
return r;
if (!arg_no_reload)
- r = daemon_reload(bus, args);
+ r = daemon_reload(argc, argv, userdata);
else
r = 0;
}
@@ -5621,12 +5735,12 @@ static int add_dependency(sd_bus *bus, char **args) {
return r;
}
-static int preset_all(sd_bus *bus, char **args) {
+static int preset_all(int argc, char *argv[], void *userdata) {
UnitFileChange *changes = NULL;
unsigned n_changes = 0;
int r;
- if (!bus || avoid_bus()) {
+ if (install_client_side()) {
r = unit_file_preset_all(arg_scope, arg_runtime, arg_root, arg_preset_mode, arg_force, &changes, &n_changes);
if (r < 0) {
@@ -5642,9 +5756,14 @@ static int preset_all(sd_bus *bus, char **args) {
} else {
_cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
_cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
+ sd_bus *bus;
polkit_agent_open_if_enabled();
+ r = acquire_bus(BUS_MANAGER, &bus);
+ if (r < 0)
+ return r;
+
r = sd_bus_call_method(
bus,
"org.freedesktop.systemd1",
@@ -5657,17 +5776,15 @@ static int preset_all(sd_bus *bus, char **args) {
unit_file_preset_mode_to_string(arg_preset_mode),
arg_runtime,
arg_force);
- if (r < 0) {
- log_error("Failed to execute operation: %s", bus_error_message(&error, r));
- return r;
- }
+ if (r < 0)
+ return log_error_errno(r, "Failed to execute operation: %s", bus_error_message(&error, r));
r = bus_deserialize_and_dump_unit_file_changes(reply, arg_quiet, NULL, NULL);
if (r < 0)
return r;
if (!arg_no_reload)
- r = daemon_reload(bus, args);
+ r = daemon_reload(argc, argv, userdata);
else
r = 0;
}
@@ -5678,25 +5795,24 @@ finish:
return r;
}
-static int unit_is_enabled(sd_bus *bus, char **args) {
+static int unit_is_enabled(int argc, char *argv[], void *userdata) {
- _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
_cleanup_strv_free_ char **names = NULL;
bool enabled;
char **name;
int r;
- r = mangle_names(args+1, &names);
+ r = mangle_names(strv_skip(argv, 1), &names);
if (r < 0)
return r;
- r = enable_sysv_units(args[0], names);
+ r = enable_sysv_units(argv[0], names);
if (r < 0)
return r;
enabled = r > 0;
- if (!bus || avoid_bus()) {
+ if (install_client_side()) {
STRV_FOREACH(name, names) {
UnitFileState state;
@@ -5717,6 +5833,13 @@ static int unit_is_enabled(sd_bus *bus, char **args) {
}
} else {
+ _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
+ sd_bus *bus;
+
+ r = acquire_bus(BUS_MANAGER, &bus);
+ if (r < 0)
+ return r;
+
STRV_FOREACH(name, names) {
_cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
const char *s;
@@ -5730,10 +5853,8 @@ static int unit_is_enabled(sd_bus *bus, char **args) {
&error,
&reply,
"s", *name);
- if (r < 0) {
- log_error("Failed to get unit file state for %s: %s", *name, bus_error_message(&error, r));
- return r;
- }
+ if (r < 0)
+ return log_error_errno(r, "Failed to get unit file state for %s: %s", *name, bus_error_message(&error, r));
r = sd_bus_message_read(reply, "s", &s);
if (r < 0)
@@ -5750,10 +5871,21 @@ static int unit_is_enabled(sd_bus *bus, char **args) {
return !enabled;
}
-static int is_system_running(sd_bus *bus, char **args) {
+static int is_system_running(int argc, char *argv[], void *userdata) {
_cleanup_free_ char *state = NULL;
+ sd_bus *bus;
int r;
+ if (arg_transport == BUS_TRANSPORT_LOCAL && !sd_booted()) {
+ if (!arg_quiet)
+ puts("offline");
+ return EXIT_FAILURE;
+ }
+
+ r = acquire_bus(BUS_MANAGER, &bus);
+ if (r < 0)
+ return r;
+
r = sd_bus_get_property_string(
bus,
"org.freedesktop.systemd1",
@@ -5788,9 +5920,8 @@ static int create_edit_temp_file(const char *new_path, const char *original_path
r = mkdir_parents(new_path, 0755);
if (r < 0) {
- log_error_errno(r, "Failed to create directories for \"%s\": %m", new_path);
free(t);
- return r;
+ return log_error_errno(r, "Failed to create directories for \"%s\": %m", new_path);
}
r = copy_file(original_path, t, 0, 0644, 0);
@@ -5845,12 +5976,16 @@ static int get_file_to_edit(const char *name, const char *user_home, const char
return log_oom();
if (arg_runtime) {
- if (access(path, F_OK) >= 0)
- return log_error_errno(EEXIST, "Refusing to create \"%s\" because it would be overridden by \"%s\" anyway.",
- run, path);
- if (path2 && access(path2, F_OK) >= 0)
- return log_error_errno(EEXIST, "Refusing to create \"%s\" because it would be overridden by \"%s\" anyway.",
- run, path2);
+ if (access(path, F_OK) >= 0) {
+ log_error("Refusing to create \"%s\" because it would be overridden by \"%s\" anyway.", run, path);
+ return -EEXIST;
+ }
+
+ if (path2 && access(path2, F_OK) >= 0) {
+ log_error("Refusing to create \"%s\" because it would be overridden by \"%s\" anyway.", run, path2);
+ return -EEXIST;
+ }
+
*ret_path = run;
run = NULL;
} else {
@@ -5943,10 +6078,8 @@ static int run_editor(char **paths) {
assert(paths);
pid = fork();
- if (pid < 0) {
- log_error_errno(errno, "Failed to fork: %m");
- return -errno;
- }
+ if (pid < 0)
+ return log_error_errno(errno, "Failed to fork: %m");
if (pid == 0) {
const char **args;
@@ -6004,7 +6137,7 @@ static int run_editor(char **paths) {
* failing.
*/
if (errno != ENOENT) {
- log_error("Failed to execute %s: %m", editor);
+ log_error_errno(errno, "Failed to execute %s: %m", editor);
_exit(EXIT_FAILURE);
}
}
@@ -6024,7 +6157,6 @@ static int find_paths_to_edit(sd_bus *bus, char **names, char ***paths) {
_cleanup_free_ char *user_home = NULL;
_cleanup_free_ char *user_runtime = NULL;
_cleanup_lookup_paths_free_ LookupPaths lp = {};
- bool avoid_bus_cache;
char **name;
int r;
@@ -6035,13 +6167,11 @@ static int find_paths_to_edit(sd_bus *bus, char **names, char ***paths) {
if (r < 0)
return r;
- avoid_bus_cache = !bus || avoid_bus();
-
STRV_FOREACH(name, names) {
_cleanup_free_ char *path = NULL;
char *new_path, *tmp_path;
- r = unit_find_paths(bus, *name, avoid_bus_cache, &lp, &path, NULL);
+ r = unit_find_paths(bus, *name, &lp, &path, NULL);
if (r < 0)
return r;
else if (r == 0)
@@ -6067,25 +6197,28 @@ static int find_paths_to_edit(sd_bus *bus, char **names, char ***paths) {
return 0;
}
-static int edit(sd_bus *bus, char **args) {
+static int edit(int argc, char *argv[], void *userdata) {
_cleanup_strv_free_ char **names = NULL;
_cleanup_strv_free_ char **paths = NULL;
char **original, **tmp;
+ sd_bus *bus;
int r;
- assert(args);
-
if (!on_tty()) {
- log_error("Cannot edit units if not on a tty");
+ log_error("Cannot edit units if not on a tty.");
return -EINVAL;
}
if (arg_transport != BUS_TRANSPORT_LOCAL) {
- log_error("Cannot remotely edit units");
+ log_error("Cannot edit units remotely.");
return -EINVAL;
}
- r = expand_names(bus, args + 1, NULL, &names);
+ r = acquire_bus(BUS_MANAGER, &bus);
+ if (r < 0)
+ return r;
+
+ r = expand_names(bus, strv_skip(argv, 1), NULL, &names);
if (r < 0)
return log_error_errno(r, "Failed to expand names: %m");
@@ -6115,8 +6248,8 @@ static int edit(sd_bus *bus, char **args) {
}
}
- if (!arg_no_reload && bus && !avoid_bus())
- r = daemon_reload(bus, args);
+ if (!arg_no_reload && bus && !install_client_side())
+ r = daemon_reload(argc, argv, userdata);
end:
STRV_FOREACH_PAIR(original, tmp, paths)
@@ -6422,9 +6555,7 @@ static int systemctl_parse_argv(int argc, char *argv[]) {
return 0;
case ARG_VERSION:
- puts(PACKAGE_STRING);
- puts(SYSTEMD_FEATURES);
- return 0;
+ return version();
case 't': {
const char *word, *state;
@@ -6598,7 +6729,8 @@ static int systemctl_parse_argv(int argc, char *argv[]) {
break;
case 's':
- if ((arg_signal = signal_from_string_try_harder(optarg)) < 0) {
+ arg_signal = signal_from_string_try_harder(optarg);
+ if (arg_signal < 0) {
log_error("Failed to parse signal string %s.", optarg);
return -EINVAL;
}
@@ -6800,7 +6932,7 @@ static int halt_parse_argv(int argc, char *argv[]) {
return 1;
}
-static int parse_time_spec(const char *t, usec_t *_u) {
+static int parse_shutdown_time_spec(const char *t, usec_t *_u) {
assert(t);
assert(_u);
@@ -6866,6 +6998,7 @@ static int shutdown_parse_argv(int argc, char *argv[]) {
{}
};
+ char **wall = NULL;
int c, r;
assert(argc >= 0);
@@ -6929,7 +7062,7 @@ static int shutdown_parse_argv(int argc, char *argv[]) {
}
if (argc > optind && arg_action != ACTION_CANCEL_SHUTDOWN) {
- r = parse_time_spec(argv[optind], &arg_when);
+ r = parse_shutdown_time_spec(argv[optind], &arg_when);
if (r < 0) {
log_error("Failed to parse time specification: %s", argv[optind]);
return r;
@@ -6939,10 +7072,16 @@ static int shutdown_parse_argv(int argc, char *argv[]) {
if (argc > optind && arg_action == ACTION_CANCEL_SHUTDOWN)
/* No time argument for shutdown cancel */
- arg_wall = argv + optind;
+ wall = argv + optind;
else if (argc > optind + 1)
/* We skip the time argument */
- arg_wall = argv + optind + 1;
+ wall = argv + optind + 1;
+
+ if (wall) {
+ arg_wall = strv_copy(wall);
+ if (!arg_wall)
+ return log_oom();
+ }
optind = argc;
@@ -7006,8 +7145,7 @@ static int telinit_parse_argv(int argc, char *argv[]) {
}
if (optind >= argc) {
- log_error("%s: required argument missing.",
- program_invocation_short_name);
+ log_error("%s: required argument missing.", program_invocation_short_name);
return -EINVAL;
}
@@ -7142,7 +7280,7 @@ _pure_ static int action_to_runlevel(void) {
}
static int talk_initctl(void) {
-
+#ifdef HAVE_SYSV_COMPAT
struct init_request request = {
.magic = INIT_MAGIC,
.sleeptime = 0,
@@ -7164,8 +7302,7 @@ static int talk_initctl(void) {
if (errno == ENOENT)
return 0;
- log_error_errno(errno, "Failed to open "INIT_FIFO": %m");
- return -errno;
+ return log_error_errno(errno, "Failed to open "INIT_FIFO": %m");
}
r = loop_write(fd, &request, sizeof(request), false);
@@ -7173,177 +7310,91 @@ static int talk_initctl(void) {
return log_error_errno(r, "Failed to write to "INIT_FIFO": %m");
return 1;
+#else
+ return 0;
+#endif
}
-static int systemctl_main(sd_bus *bus, int argc, char *argv[], int bus_error) {
-
- static const struct {
- const char* verb;
- const enum {
- MORE,
- LESS,
- EQUAL
- } argc_cmp;
- const int argc;
- int (* const dispatch)(sd_bus *bus, char **args);
- const enum {
- NOBUS = 1,
- FORCE,
- } bus;
- } verbs[] = {
- { "list-units", MORE, 0, list_units },
- { "list-unit-files", MORE, 1, list_unit_files, NOBUS },
- { "list-sockets", MORE, 1, list_sockets },
- { "list-timers", MORE, 1, list_timers },
- { "list-jobs", MORE, 1, list_jobs },
- { "list-machines", MORE, 1, list_machines },
- { "clear-jobs", EQUAL, 1, daemon_reload },
- { "cancel", MORE, 2, cancel_job },
- { "start", MORE, 2, start_unit },
- { "stop", MORE, 2, start_unit },
- { "condstop", MORE, 2, start_unit }, /* For compatibility with ALTLinux */
- { "reload", MORE, 2, start_unit },
- { "restart", MORE, 2, start_unit },
- { "try-restart", MORE, 2, start_unit },
- { "reload-or-restart", MORE, 2, start_unit },
- { "reload-or-try-restart", MORE, 2, start_unit },
- { "force-reload", MORE, 2, start_unit }, /* For compatibility with SysV */
- { "condreload", MORE, 2, start_unit }, /* For compatibility with ALTLinux */
- { "condrestart", MORE, 2, start_unit }, /* For compatibility with RH */
- { "isolate", EQUAL, 2, start_unit },
- { "kill", MORE, 2, kill_unit },
- { "is-active", MORE, 2, check_unit_active },
- { "check", MORE, 2, check_unit_active },
- { "is-failed", MORE, 2, check_unit_failed },
- { "show", MORE, 1, show },
- { "cat", MORE, 2, cat, NOBUS },
- { "status", MORE, 1, show },
- { "help", MORE, 2, show },
- { "snapshot", LESS, 2, snapshot },
- { "delete", MORE, 2, delete_snapshot },
- { "daemon-reload", EQUAL, 1, daemon_reload },
- { "daemon-reexec", EQUAL, 1, daemon_reload },
- { "show-environment", EQUAL, 1, show_environment },
- { "set-environment", MORE, 2, set_environment },
- { "unset-environment", MORE, 2, set_environment },
- { "import-environment", MORE, 1, import_environment},
- { "halt", EQUAL, 1, start_special, FORCE },
- { "poweroff", EQUAL, 1, start_special, FORCE },
- { "reboot", MORE, 1, start_special, FORCE },
- { "kexec", EQUAL, 1, start_special },
- { "suspend", EQUAL, 1, start_special },
- { "hibernate", EQUAL, 1, start_special },
- { "hybrid-sleep", EQUAL, 1, start_special },
- { "default", EQUAL, 1, start_special },
- { "rescue", EQUAL, 1, start_special },
- { "emergency", EQUAL, 1, start_special },
- { "exit", LESS, 2, start_special },
- { "reset-failed", MORE, 1, reset_failed },
- { "enable", MORE, 2, enable_unit, NOBUS },
- { "disable", MORE, 2, enable_unit, NOBUS },
- { "is-enabled", MORE, 2, unit_is_enabled, NOBUS },
- { "reenable", MORE, 2, enable_unit, NOBUS },
- { "preset", MORE, 2, enable_unit, NOBUS },
- { "preset-all", EQUAL, 1, preset_all, NOBUS },
- { "mask", MORE, 2, enable_unit, NOBUS },
- { "unmask", MORE, 2, enable_unit, NOBUS },
- { "link", MORE, 2, enable_unit, NOBUS },
- { "switch-root", MORE, 2, switch_root },
- { "list-dependencies", LESS, 2, list_dependencies },
- { "set-default", EQUAL, 2, set_default, NOBUS },
- { "get-default", EQUAL, 1, get_default, NOBUS },
- { "set-property", MORE, 3, set_property },
- { "is-system-running", EQUAL, 1, is_system_running },
- { "add-wants", MORE, 3, add_dependency, NOBUS },
- { "add-requires", MORE, 3, add_dependency, NOBUS },
- { "edit", MORE, 2, edit, NOBUS },
+static int systemctl_main(int argc, char *argv[]) {
+
+ static const Verb verbs[] = {
+ { "list-units", VERB_ANY, 1, VERB_DEFAULT, list_units },
+ { "list-unit-files", VERB_ANY, 1, 0, list_unit_files },
+ { "list-sockets", VERB_ANY, 1, 0, list_sockets },
+ { "list-timers", VERB_ANY, 1, 0, list_timers },
+ { "list-jobs", VERB_ANY, 1, 0, list_jobs },
+ { "list-machines", VERB_ANY, 1, 0, list_machines },
+ { "clear-jobs", VERB_ANY, 1, 0, daemon_reload },
+ { "cancel", 2, VERB_ANY, 0, cancel_job },
+ { "start", 2, VERB_ANY, 0, start_unit },
+ { "stop", 2, VERB_ANY, 0, start_unit },
+ { "condstop", 2, VERB_ANY, 0, start_unit }, /* For compatibility with ALTLinux */
+ { "reload", 2, VERB_ANY, 0, start_unit },
+ { "restart", 2, VERB_ANY, 0, start_unit },
+ { "try-restart", 2, VERB_ANY, 0, start_unit },
+ { "reload-or-restart", 2, VERB_ANY, 0, start_unit },
+ { "reload-or-try-restart", 2, VERB_ANY, 0, start_unit },
+ { "force-reload", 2, VERB_ANY, 0, start_unit }, /* For compatibility with SysV */
+ { "condreload", 2, VERB_ANY, 0, start_unit }, /* For compatibility with ALTLinux */
+ { "condrestart", 2, VERB_ANY, 0, start_unit }, /* For compatibility with RH */
+ { "isolate", 2, 2, 0, start_unit },
+ { "kill", 2, VERB_ANY, 0, kill_unit },
+ { "is-active", 2, VERB_ANY, 0, check_unit_active },
+ { "check", 2, VERB_ANY, 0, check_unit_active },
+ { "is-failed", 2, VERB_ANY, 0, check_unit_failed },
+ { "show", VERB_ANY, VERB_ANY, 0, show },
+ { "cat", 2, VERB_ANY, 0, cat },
+ { "status", VERB_ANY, VERB_ANY, 0, show },
+ { "help", VERB_ANY, VERB_ANY, 0, show },
+ { "snapshot", VERB_ANY, 2, 0, snapshot },
+ { "delete", 2, VERB_ANY, 0, delete_snapshot },
+ { "daemon-reload", VERB_ANY, 1, 0, daemon_reload },
+ { "daemon-reexec", VERB_ANY, 1, 0, daemon_reload },
+ { "show-environment", VERB_ANY, 1, 0, show_environment },
+ { "set-environment", 2, VERB_ANY, 0, set_environment },
+ { "unset-environment", 2, VERB_ANY, 0, set_environment },
+ { "import-environment", VERB_ANY, VERB_ANY, 0, import_environment},
+ { "halt", VERB_ANY, 1, 0, start_special },
+ { "poweroff", VERB_ANY, 1, 0, start_special },
+ { "reboot", VERB_ANY, 2, 0, start_special },
+ { "kexec", VERB_ANY, 1, 0, start_special },
+ { "suspend", VERB_ANY, 1, 0, start_special },
+ { "hibernate", VERB_ANY, 1, 0, start_special },
+ { "hybrid-sleep", VERB_ANY, 1, 0, start_special },
+ { "default", VERB_ANY, 1, 0, start_special },
+ { "rescue", VERB_ANY, 1, 0, start_special },
+ { "emergency", VERB_ANY, 1, 0, start_special },
+ { "exit", VERB_ANY, 2, 0, start_special },
+ { "reset-failed", VERB_ANY, VERB_ANY, 0, reset_failed },
+ { "enable", 2, VERB_ANY, 0, enable_unit },
+ { "disable", 2, VERB_ANY, 0, enable_unit },
+ { "is-enabled", 2, VERB_ANY, 0, unit_is_enabled },
+ { "reenable", 2, VERB_ANY, 0, enable_unit },
+ { "preset", 2, VERB_ANY, 0, enable_unit },
+ { "preset-all", VERB_ANY, 1, 0, preset_all },
+ { "mask", 2, VERB_ANY, 0, enable_unit },
+ { "unmask", 2, VERB_ANY, 0, enable_unit },
+ { "link", 2, VERB_ANY, 0, enable_unit },
+ { "switch-root", 2, VERB_ANY, 0, switch_root },
+ { "list-dependencies", VERB_ANY, 2, 0, list_dependencies },
+ { "set-default", 2, 2, 0, set_default },
+ { "get-default", VERB_ANY, 1, 0, get_default, },
+ { "set-property", 3, VERB_ANY, 0, set_property },
+ { "is-system-running", VERB_ANY, 1, 0, is_system_running },
+ { "add-wants", 3, VERB_ANY, 0, add_dependency },
+ { "add-requires", 3, VERB_ANY, 0, add_dependency },
+ { "edit", 2, VERB_ANY, 0, edit },
{}
- }, *verb = verbs;
-
- int left;
-
- assert(argc >= 0);
- assert(argv);
-
- left = argc - optind;
-
- /* Special rule: no arguments (left == 0) means "list-units" */
- if (left > 0) {
- if (streq(argv[optind], "help") && !argv[optind+1]) {
- log_error("This command expects one or more "
- "unit names. Did you mean --help?");
- return -EINVAL;
- }
-
- for (; verb->verb; verb++)
- if (streq(argv[optind], verb->verb))
- goto found;
-
- log_error("Unknown operation '%s'.", argv[optind]);
- return -EINVAL;
- }
-found:
-
- switch (verb->argc_cmp) {
-
- case EQUAL:
- if (left != verb->argc) {
- log_error("Invalid number of arguments.");
- return -EINVAL;
- }
-
- break;
-
- case MORE:
- if (left < verb->argc) {
- log_error("Too few arguments.");
- return -EINVAL;
- }
-
- break;
-
- case LESS:
- if (left > verb->argc) {
- log_error("Too many arguments.");
- return -EINVAL;
- }
-
- break;
-
- default:
- assert_not_reached("Unknown comparison operator.");
- }
-
- /* Require a bus connection for all operations but
- * enable/disable */
- if (verb->bus == NOBUS) {
- if (!bus && !avoid_bus()) {
- log_error_errno(bus_error, "Failed to get D-Bus connection: %m");
- return -EIO;
- }
-
- } else {
- if (running_in_chroot() > 0) {
- log_info("Running in chroot, ignoring request.");
- return 0;
- }
-
- if ((verb->bus != FORCE || arg_force <= 0) && !bus) {
- log_error_errno(bus_error, "Failed to get D-Bus connection: %m");
- return -EIO;
- }
- }
+ };
- return verb->dispatch(bus, argv + optind);
+ return dispatch_verb(argc, argv, verbs, NULL);
}
-static int reload_with_fallback(sd_bus *bus) {
+static int reload_with_fallback(void) {
- if (bus) {
- /* First, try systemd via D-Bus. */
- if (daemon_reload(bus, NULL) >= 0)
- return 0;
- }
+ /* First, try systemd via D-Bus. */
+ if (daemon_reload(0, NULL, NULL) >= 0)
+ return 0;
/* Nothing else worked, so let's try signals */
assert(arg_action == ACTION_RELOAD || arg_action == ACTION_REEXEC);
@@ -7354,25 +7405,19 @@ static int reload_with_fallback(sd_bus *bus) {
return 0;
}
-static int start_with_fallback(sd_bus *bus) {
+static int start_with_fallback(void) {
- if (bus) {
- /* First, try systemd via D-Bus. */
- if (start_unit(bus, NULL) >= 0)
- goto done;
- }
+ /* First, try systemd via D-Bus. */
+ if (start_unit(0, NULL, NULL) >= 0)
+ return 0;
/* Nothing else worked, so let's try
* /dev/initctl */
if (talk_initctl() > 0)
- goto done;
+ return 0;
log_error("Failed to talk to init daemon.");
return -EIO;
-
-done:
- warn_wall(arg_action);
- return 0;
}
static int halt_now(enum action a) {
@@ -7380,22 +7425,22 @@ static int halt_now(enum action a) {
/* The kernel will automaticall flush ATA disks and suchlike
* on reboot(), but the file systems need to be synce'd
* explicitly in advance. */
- sync();
+ (void) sync();
/* Make sure C-A-D is handled by the kernel from this point
* on... */
- reboot(RB_ENABLE_CAD);
+ (void) reboot(RB_ENABLE_CAD);
switch (a) {
case ACTION_HALT:
log_info("Halting.");
- reboot(RB_HALT_SYSTEM);
+ (void) reboot(RB_HALT_SYSTEM);
return -errno;
case ACTION_POWEROFF:
log_info("Powering off.");
- reboot(RB_POWER_OFF);
+ (void) reboot(RB_POWER_OFF);
return -errno;
case ACTION_KEXEC:
@@ -7404,12 +7449,11 @@ static int halt_now(enum action a) {
if (read_one_line_file(REBOOT_PARAM_FILE, &param) >= 0) {
log_info("Rebooting with argument '%s'.", param);
- syscall(SYS_reboot, LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2,
- LINUX_REBOOT_CMD_RESTART2, param);
+ (void) syscall(SYS_reboot, LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, LINUX_REBOOT_CMD_RESTART2, param);
}
log_info("Rebooting.");
- reboot(RB_AUTOBOOT);
+ (void) reboot(RB_AUTOBOOT);
return -errno;
}
@@ -7418,17 +7462,73 @@ static int halt_now(enum action a) {
}
}
-static int halt_main(sd_bus *bus) {
+static int logind_schedule_shutdown(void) {
+
+#ifdef HAVE_LOGIND
+ _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
+ char date[FORMAT_TIMESTAMP_MAX];
+ const char *action;
+ sd_bus *bus;
int r;
- r = check_inhibitors(bus, arg_action);
+ (void) logind_set_wall_message();
+
+ r = acquire_bus(BUS_FULL, &bus);
if (r < 0)
return r;
+ switch (arg_action) {
+ case ACTION_HALT:
+ action = "halt";
+ break;
+ case ACTION_POWEROFF:
+ action = "poweroff";
+ break;
+ case ACTION_KEXEC:
+ action = "kexec";
+ break;
+ default:
+ action = "reboot";
+ break;
+ }
+
+ if (arg_dry)
+ action = strjoina("dry-", action);
+
+ r = sd_bus_call_method(
+ bus,
+ "org.freedesktop.login1",
+ "/org/freedesktop/login1",
+ "org.freedesktop.login1.Manager",
+ "ScheduleShutdown",
+ &error,
+ NULL,
+ "st",
+ action,
+ arg_when);
+ if (r < 0)
+ return log_warning_errno(r, "Failed to call ScheduleShutdown in logind, proceeding with immediate shutdown: %s", bus_error_message(&error, r));
+
+ log_info("Shutdown scheduled for %s, use 'shutdown -c' to cancel.", format_timestamp(date, sizeof(date), arg_when));
+ return 0;
+#else
+ log_error("Cannot schedule shutdown without logind support, proceeding with immediate shutdown.");
+ return -ENOSYS;
+#endif
+}
+
+static int halt_main(void) {
+ int r;
+
+ r = logind_check_inhibitors(arg_action);
+ if (r < 0)
+ return r;
+
+ if (arg_when > 0)
+ return logind_schedule_shutdown();
+
if (geteuid() != 0) {
- if (arg_when > 0 ||
- arg_dry ||
- arg_force > 0) {
+ if (arg_dry || arg_force > 0) {
log_error("Must be root.");
return -EPERM;
}
@@ -7436,101 +7536,21 @@ static int halt_main(sd_bus *bus) {
/* Try logind if we are a normal user and no special
* mode applies. Maybe PolicyKit allows us to shutdown
* the machine. */
- if (IN_SET(arg_action,
- ACTION_POWEROFF,
- ACTION_REBOOT)) {
- r = reboot_with_logind(bus, arg_action);
+ if (IN_SET(arg_action, ACTION_POWEROFF, ACTION_REBOOT)) {
+ r = logind_reboot(arg_action);
if (r >= 0)
return r;
if (IN_SET(r, -EOPNOTSUPP, -EINPROGRESS))
- /* requested operation is not supported or already in progress */
+ /* requested operation is not
+ * supported on the local system or
+ * already in progress */
return r;
/* on all other errors, try low-level operation */
}
}
- if (arg_when > 0) {
- _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
- _cleanup_bus_flush_close_unref_ sd_bus *b = NULL;
- _cleanup_free_ char *m = NULL;
- const char *action;
-
- assert(geteuid() == 0);
-
- if (avoid_bus()) {
- log_error("Unable to perform operation without bus connection.");
- return -ENOSYS;
- }
-
- r = sd_bus_open_system(&b);
- if (r < 0)
- return log_error_errno(r, "Unable to open system bus: %m");
-
- m = strv_join(arg_wall, " ");
- if (!m)
- return log_oom();
-
- r = sd_bus_call_method(
- b,
- "org.freedesktop.login1",
- "/org/freedesktop/login1",
- "org.freedesktop.login1.Manager",
- "SetWallMessage",
- &error,
- NULL,
- "sb",
- m,
- !arg_no_wall);
-
- if (r < 0) {
- log_warning_errno(r, "Failed to set wall message, ignoring: %s",
- bus_error_message(&error, r));
- sd_bus_error_free(&error);
- }
-
- switch (arg_action) {
- case ACTION_HALT:
- action = "halt";
- break;
- case ACTION_POWEROFF:
- action = "poweroff";
- break;
- case ACTION_KEXEC:
- action = "kexec";
- break;
- default:
- action = "reboot";
- break;
- }
-
- if (arg_dry)
- action = strjoina("dry-", action);
-
- r = sd_bus_call_method(
- b,
- "org.freedesktop.login1",
- "/org/freedesktop/login1",
- "org.freedesktop.login1.Manager",
- "ScheduleShutdown",
- &error,
- NULL,
- "st",
- action,
- arg_when);
- if (r < 0)
- log_warning_errno(r, "Failed to call ScheduleShutdown in logind, proceeding with immediate shutdown: %s",
- bus_error_message(&error, r));
- else {
- char date[FORMAT_TIMESTAMP_MAX];
-
- log_info("Shutdown scheduled for %s, use 'shutdown -c' to cancel.",
- format_timestamp(date, sizeof(date), arg_when));
- return 0;
- }
- }
-
if (!arg_dry && !arg_force)
- return start_with_fallback(bus);
+ return start_with_fallback();
assert(geteuid() == 0);
@@ -7548,9 +7568,7 @@ static int halt_main(sd_bus *bus) {
return 0;
r = halt_now(arg_action);
- log_error_errno(r, "Failed to reboot: %m");
-
- return r;
+ return log_error_errno(r, "Failed to reboot: %m");
}
static int runlevel_main(void) {
@@ -7569,8 +7587,37 @@ static int runlevel_main(void) {
return 0;
}
+static int logind_cancel_shutdown(void) {
+#ifdef HAVE_LOGIND
+ _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
+ sd_bus *bus;
+ int r;
+
+ r = acquire_bus(BUS_FULL, &bus);
+ if (r < 0)
+ return r;
+
+ (void) logind_set_wall_message();
+
+ r = sd_bus_call_method(
+ bus,
+ "org.freedesktop.login1",
+ "/org/freedesktop/login1",
+ "org.freedesktop.login1.Manager",
+ "CancelScheduledShutdown",
+ &error,
+ NULL, NULL);
+ if (r < 0)
+ return log_warning_errno(r, "Failed to talk to logind, shutdown hasn't been cancelled: %s", bus_error_message(&error, r));
+
+ return 0;
+#else
+ log_error("Not compiled with logind support, cannot cancel scheduled shutdowns.");
+ return -ENOSYS;
+#endif
+}
+
int main(int argc, char*argv[]) {
- _cleanup_bus_flush_close_unref_ sd_bus *bus = NULL;
int r;
setlocale(LC_ALL, "");
@@ -7586,39 +7633,26 @@ int main(int argc, char*argv[]) {
if (r <= 0)
goto finish;
- /* /sbin/runlevel doesn't need to communicate via D-Bus, so
- * let's shortcut this */
- if (arg_action == ACTION_RUNLEVEL) {
- r = runlevel_main();
- goto finish;
- }
-
if (running_in_chroot() > 0 && arg_action != ACTION_SYSTEMCTL) {
log_info("Running in chroot, ignoring request.");
r = 0;
goto finish;
}
- if (!avoid_bus())
- r = bus_open_transport_systemd(arg_transport, arg_host, arg_scope != UNIT_FILE_SYSTEM, &bus);
-
- if (bus)
- sd_bus_set_allow_interactive_authorization(bus, arg_ask_password);
-
/* systemctl_main() will print an error message for the bus
* connection, but only if it needs to */
switch (arg_action) {
case ACTION_SYSTEMCTL:
- r = systemctl_main(bus, argc, argv, r);
+ r = systemctl_main(argc, argv);
break;
case ACTION_HALT:
case ACTION_POWEROFF:
case ACTION_REBOOT:
case ACTION_KEXEC:
- r = halt_main(bus);
+ r = halt_main();
break;
case ACTION_RUNLEVEL2:
@@ -7628,69 +7662,22 @@ int main(int argc, char*argv[]) {
case ACTION_RESCUE:
case ACTION_EMERGENCY:
case ACTION_DEFAULT:
- r = start_with_fallback(bus);
+ r = start_with_fallback();
break;
case ACTION_RELOAD:
case ACTION_REEXEC:
- r = reload_with_fallback(bus);
+ r = reload_with_fallback();
break;
- case ACTION_CANCEL_SHUTDOWN: {
- _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
- _cleanup_bus_flush_close_unref_ sd_bus *b = NULL;
- _cleanup_free_ char *m = NULL;
-
- if (avoid_bus()) {
- log_error("Unable to perform operation without bus connection.");
- return -ENOSYS;
- }
-
- r = sd_bus_open_system(&b);
- if (r < 0)
- return log_error_errno(r, "Unable to open system bus: %m");
-
- if (arg_wall) {
- m = strv_join(arg_wall, " ");
- if (!m) {
- r = log_oom();
- goto finish;
- }
- }
-
- r = sd_bus_call_method(
- b,
- "org.freedesktop.login1",
- "/org/freedesktop/login1",
- "org.freedesktop.login1.Manager",
- "SetWallMessage",
- &error,
- NULL,
- "sb",
- m,
- !arg_no_wall);
-
- if (r < 0) {
- log_warning_errno(r, "Failed to set wall message, ignoring: %s",
- bus_error_message(&error, r));
- sd_bus_error_free(&error);
- }
-
- r = sd_bus_call_method(
- b,
- "org.freedesktop.login1",
- "/org/freedesktop/login1",
- "org.freedesktop.login1.Manager",
- "CancelScheduledShutdown",
- &error,
- NULL, NULL);
- if (r < 0)
- log_warning_errno(r, "Failed to talk to logind, shutdown hasn't been cancelled: %s",
- bus_error_message(&error, r));
+ case ACTION_CANCEL_SHUTDOWN:
+ r = logind_cancel_shutdown();
break;
- }
case ACTION_RUNLEVEL:
+ r = runlevel_main();
+ break;
+
case _ACTION_INVALID:
default:
assert_not_reached("Unknown action");
@@ -7705,7 +7692,9 @@ finish:
strv_free(arg_states);
strv_free(arg_properties);
- sd_bus_default_flush_close();
+ strv_free(arg_wall);
+
+ release_busses();
return r < 0 ? EXIT_FAILURE : r;
}
diff --git a/src/systemd/sd-bus.h b/src/systemd/sd-bus.h
index 0883203ae7..43cf247cdf 100644
--- a/src/systemd/sd-bus.h
+++ b/src/systemd/sd-bus.h
@@ -420,7 +420,9 @@ int sd_bus_error_add_map(const sd_bus_error_map *map);
/* Label escaping */
int sd_bus_path_encode(const char *prefix, const char *external_id, char **ret_path);
+int sd_bus_path_encode_many(char **out, const char *path_template, ...);
int sd_bus_path_decode(const char *path, const char *prefix, char **ret_external_id);
+int sd_bus_path_decode_many(const char *path, const char *path_template, ...);
/* Tracking peers */
diff --git a/src/sysusers/sysusers.c b/src/sysusers/sysusers.c
index aaa33354f4..07494e764b 100644
--- a/src/sysusers/sysusers.c
+++ b/src/sysusers/sysusers.c
@@ -19,26 +19,25 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-#include <pwd.h>
+#include <getopt.h>
#include <grp.h>
-#include <shadow.h>
#include <gshadow.h>
-#include <getopt.h>
+#include <pwd.h>
+#include <shadow.h>
#include <utmp.h>
-#include "util.h"
-#include "hashmap.h"
-#include "specifier.h"
-#include "path-util.h"
-#include "build.h"
-#include "strv.h"
#include "conf-files.h"
#include "copy.h"
-#include "utf8.h"
#include "fileio-label.h"
-#include "uid-range.h"
-#include "selinux-util.h"
#include "formats-util.h"
+#include "hashmap.h"
+#include "path-util.h"
+#include "selinux-util.h"
+#include "specifier.h"
+#include "strv.h"
+#include "uid-range.h"
+#include "utf8.h"
+#include "util.h"
typedef enum ItemType {
ADD_USER = 'u',
@@ -1767,9 +1766,7 @@ static int parse_argv(int argc, char *argv[]) {
return 0;
case ARG_VERSION:
- puts(PACKAGE_STRING);
- puts(SYSTEMD_FEATURES);
- return 0;
+ return version();
case ARG_ROOT:
free(arg_root);
diff --git a/src/test/test-strv.c b/src/test/test-strv.c
index bff43950a9..cc47fd4d34 100644
--- a/src/test/test-strv.c
+++ b/src/test/test-strv.c
@@ -569,6 +569,28 @@ static void test_strv_shell_escape(void) {
assert_se(streq_ptr(v[3], NULL));
}
+static void test_strv_skip_one(char **a, size_t n, char **b) {
+ a = strv_skip(a, n);
+ assert_se(strv_equal(a, b));
+}
+
+static void test_strv_skip(void) {
+ test_strv_skip_one(STRV_MAKE("foo", "bar", "baz"), 0, STRV_MAKE("foo", "bar", "baz"));
+ test_strv_skip_one(STRV_MAKE("foo", "bar", "baz"), 1, STRV_MAKE("bar", "baz"));
+ test_strv_skip_one(STRV_MAKE("foo", "bar", "baz"), 2, STRV_MAKE("baz"));
+ test_strv_skip_one(STRV_MAKE("foo", "bar", "baz"), 3, STRV_MAKE(NULL));
+ test_strv_skip_one(STRV_MAKE("foo", "bar", "baz"), 4, STRV_MAKE(NULL));
+ test_strv_skip_one(STRV_MAKE("foo", "bar", "baz"), 55, STRV_MAKE(NULL));
+
+ test_strv_skip_one(STRV_MAKE("quux"), 0, STRV_MAKE("quux"));
+ test_strv_skip_one(STRV_MAKE("quux"), 1, STRV_MAKE(NULL));
+ test_strv_skip_one(STRV_MAKE("quux"), 55, STRV_MAKE(NULL));
+
+ test_strv_skip_one(STRV_MAKE(NULL), 0, STRV_MAKE(NULL));
+ test_strv_skip_one(STRV_MAKE(NULL), 1, STRV_MAKE(NULL));
+ test_strv_skip_one(STRV_MAKE(NULL), 55, STRV_MAKE(NULL));
+}
+
int main(int argc, char *argv[]) {
test_specifier_printf();
test_strv_foreach();
@@ -627,6 +649,7 @@ int main(int argc, char *argv[]) {
test_strv_is_uniq();
test_strv_reverse();
test_strv_shell_escape();
+ test_strv_skip();
return 0;
}
diff --git a/src/timedate/timedatectl.c b/src/timedate/timedatectl.c
index 12a7ed6718..68fbe3f5b8 100644
--- a/src/timedate/timedatectl.c
+++ b/src/timedate/timedatectl.c
@@ -20,20 +20,20 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-#include <stdlib.h>
-#include <stdbool.h>
#include <getopt.h>
#include <locale.h>
+#include <stdbool.h>
+#include <stdlib.h>
#include "sd-bus.h"
-#include "bus-util.h"
+
#include "bus-error.h"
-#include "util.h"
+#include "bus-util.h"
+#include "pager.h"
#include "spawn-polkit-agent.h"
-#include "build.h"
#include "strv.h"
-#include "pager.h"
#include "terminal-util.h"
+#include "util.h"
static bool arg_no_pager = false;
static bool arg_ask_password = true;
@@ -374,9 +374,7 @@ static int parse_argv(int argc, char *argv[]) {
return 0;
case ARG_VERSION:
- puts(PACKAGE_STRING);
- puts(SYSTEMD_FEATURES);
- return 0;
+ return version();
case 'H':
arg_transport = BUS_TRANSPORT_REMOTE;
@@ -502,7 +500,7 @@ int main(int argc, char *argv[]) {
if (r <= 0)
goto finish;
- r = bus_open_transport(arg_transport, arg_host, false, &bus);
+ r = bus_connect_transport(arg_transport, arg_host, false, &bus);
if (r < 0) {
log_error_errno(r, "Failed to create bus connection: %m");
goto finish;
diff --git a/src/tmpfiles/tmpfiles.c b/src/tmpfiles/tmpfiles.c
index 8f29256c6d..d219764bc6 100644
--- a/src/tmpfiles/tmpfiles.c
+++ b/src/tmpfiles/tmpfiles.c
@@ -20,43 +20,42 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-#include <unistd.h>
-#include <fcntl.h>
+#include <dirent.h>
#include <errno.h>
-#include <string.h>
+#include <fcntl.h>
+#include <fnmatch.h>
+#include <getopt.h>
+#include <glob.h>
#include <limits.h>
-#include <dirent.h>
+#include <linux/fs.h>
+#include <stdbool.h>
+#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
-#include <stddef.h>
-#include <getopt.h>
-#include <stdbool.h>
-#include <time.h>
-#include <glob.h>
-#include <fnmatch.h>
+#include <string.h>
#include <sys/stat.h>
#include <sys/xattr.h>
-#include <linux/fs.h>
+#include <time.h>
+#include <unistd.h>
+#include "acl-util.h"
+#include "btrfs-util.h"
+#include "capability.h"
+#include "conf-files.h"
+#include "copy.h"
+#include "formats-util.h"
+#include "label.h"
#include "log.h"
-#include "util.h"
#include "macro.h"
#include "missing.h"
#include "mkdir.h"
#include "path-util.h"
-#include "strv.h"
-#include "label.h"
-#include "set.h"
-#include "conf-files.h"
-#include "capability.h"
-#include "specifier.h"
-#include "build.h"
-#include "copy.h"
#include "rm-rf.h"
#include "selinux-util.h"
-#include "btrfs-util.h"
-#include "acl-util.h"
-#include "formats-util.h"
+#include "set.h"
+#include "specifier.h"
+#include "strv.h"
+#include "util.h"
/* This reads all files listed in /etc/tmpfiles.d/?*.conf and creates
* them in the file system. This is intended to be used to create
@@ -2090,9 +2089,7 @@ static int parse_argv(int argc, char *argv[]) {
return 0;
case ARG_VERSION:
- puts(PACKAGE_STRING);
- puts(SYSTEMD_FEATURES);
- return 0;
+ return version();
case ARG_CREATE:
arg_create = true;
diff --git a/src/tty-ask-password-agent/tty-ask-password-agent.c b/src/tty-ask-password-agent/tty-ask-password-agent.c
index 82cbf95f1e..4630eb94f1 100644
--- a/src/tty-ask-password-agent/tty-ask-password-agent.c
+++ b/src/tty-ask-password-agent/tty-ask-password-agent.c
@@ -19,32 +19,31 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-#include <stdbool.h>
#include <errno.h>
+#include <fcntl.h>
+#include <getopt.h>
+#include <poll.h>
+#include <stdbool.h>
+#include <stddef.h>
#include <string.h>
+#include <sys/inotify.h>
+#include <sys/signalfd.h>
#include <sys/socket.h>
#include <sys/un.h>
-#include <stddef.h>
-#include <poll.h>
-#include <sys/inotify.h>
#include <unistd.h>
-#include <getopt.h>
-#include <sys/signalfd.h>
-#include <fcntl.h>
-#include "util.h"
+#include "ask-password-api.h"
+#include "conf-parser.h"
+#include "def.h"
#include "mkdir.h"
#include "path-util.h"
-#include "conf-parser.h"
-#include "utmp-wtmp.h"
+#include "process-util.h"
+#include "signal-util.h"
#include "socket-util.h"
-#include "ask-password-api.h"
#include "strv.h"
-#include "build.h"
-#include "def.h"
-#include "process-util.h"
#include "terminal-util.h"
-#include "signal-util.h"
+#include "util.h"
+#include "utmp-wtmp.h"
static enum {
ACTION_LIST,
@@ -257,7 +256,7 @@ static int parse_password(const char *filename, char **wall) {
if (asprintf(&_wall,
"%s%sPassword entry required for \'%s\' (PID %u).\r\n"
"Please enter password with the systemd-tty-ask-password-agent tool!",
- *wall ? *wall : "",
+ strempty(*wall),
*wall ? "\r\n\r\n" : "",
message,
pid) < 0)
@@ -571,9 +570,7 @@ static int parse_argv(int argc, char *argv[]) {
return 0;
case ARG_VERSION:
- puts(PACKAGE_STRING);
- puts(SYSTEMD_FEATURES);
- return 0;
+ return version();
case ARG_LIST:
arg_action = ACTION_LIST;
@@ -628,15 +625,14 @@ int main(int argc, char *argv[]) {
goto finish;
if (arg_console) {
- setsid();
- release_terminal();
+ (void) setsid();
+ (void) release_terminal();
}
if (IN_SET(arg_action, ACTION_WATCH, ACTION_WALL))
r = watch_passwords();
else
r = show_passwords();
-
if (r < 0)
log_error_errno(r, "Error: %m");
diff --git a/src/update-utmp/update-utmp.c b/src/update-utmp/update-utmp.c
index b2998dce43..bcabf65a36 100644
--- a/src/update-utmp/update-utmp.c
+++ b/src/update-utmp/update-utmp.c
@@ -62,7 +62,7 @@ static usec_t get_startup_time(Context *c) {
&error,
't', &t);
if (r < 0) {
- log_error("Failed to get timestamp: %s", bus_error_message(&error, -r));
+ log_error_errno(r, "Failed to get timestamp: %s", bus_error_message(&error, r));
return 0;
}
@@ -105,10 +105,8 @@ static int get_current_runlevel(Context *c) {
"ActiveState",
&error,
&state);
- if (r < 0) {
- log_warning("Failed to get state: %s", bus_error_message(&error, -r));
- return r;
- }
+ if (r < 0)
+ return log_warning_errno(r, "Failed to get state: %s", bus_error_message(&error, r));
if (streq(state, "active") || streq(state, "reloading"))
return table[i].runlevel;
@@ -130,8 +128,7 @@ static int on_reboot(Context *c) {
if (c->audit_fd >= 0)
if (audit_log_user_comm_message(c->audit_fd, AUDIT_SYSTEM_BOOT, "", "systemd-update-utmp", NULL, NULL, NULL, 1) < 0 &&
errno != EPERM) {
- r = log_error_errno(errno,
- "Failed to send audit message: %m");
+ r = log_error_errno(errno, "Failed to send audit message: %m");
}
#endif
@@ -160,8 +157,7 @@ static int on_shutdown(Context *c) {
if (c->audit_fd >= 0)
if (audit_log_user_comm_message(c->audit_fd, AUDIT_SYSTEM_SHUTDOWN, "", "systemd-update-utmp", NULL, NULL, NULL, 1) < 0 &&
errno != EPERM) {
- r = log_error_errno(errno,
- "Failed to send audit message: %m");
+ r = log_error_errno(errno, "Failed to send audit message: %m");
}
#endif
@@ -211,8 +207,7 @@ static int on_runlevel(Context *c) {
return log_oom();
if (audit_log_user_comm_message(c->audit_fd, AUDIT_SYSTEM_RUNLEVEL, s, "systemd-update-utmp", NULL, NULL, NULL, 1) < 0 && errno != EPERM)
- r = log_error_errno(errno,
- "Failed to send audit message: %m");
+ r = log_error_errno(errno, "Failed to send audit message: %m");
}
#endif
@@ -256,7 +251,7 @@ int main(int argc, char *argv[]) {
if (c.audit_fd < 0 && errno != EAFNOSUPPORT && errno != EPROTONOSUPPORT)
log_error_errno(errno, "Failed to connect to audit log: %m");
#endif
- r = bus_open_system_systemd(&c.bus);
+ r = bus_connect_system_systemd(&c.bus);
if (r < 0) {
log_error_errno(r, "Failed to get D-Bus connection: %m");
r = -EIO;
@@ -284,6 +279,6 @@ finish:
audit_close(c.audit_fd);
#endif
- sd_bus_unref(c.bus);
+ sd_bus_flush_close_unref(c.bus);
return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
}
diff --git a/units/systemd-hostnamed.service.in b/units/systemd-hostnamed.service.in
index cc88ecd0db..b7079e4a7c 100644
--- a/units/systemd-hostnamed.service.in
+++ b/units/systemd-hostnamed.service.in
@@ -14,7 +14,7 @@ Documentation=http://www.freedesktop.org/wiki/Software/systemd/hostnamed
ExecStart=@rootlibexecdir@/systemd-hostnamed
BusName=org.freedesktop.hostname1
CapabilityBoundingSet=CAP_SYS_ADMIN
-WatchdogSec=1min
+WatchdogSec=3min
PrivateTmp=yes
PrivateDevices=yes
PrivateNetwork=yes
diff --git a/units/systemd-importd.service.in b/units/systemd-importd.service.in
index 403f15316d..d3238cf8f5 100644
--- a/units/systemd-importd.service.in
+++ b/units/systemd-importd.service.in
@@ -14,5 +14,5 @@ ExecStart=@rootlibexecdir@/systemd-importd
BusName=org.freedesktop.import1
CapabilityBoundingSet=CAP_CHOWN CAP_FOWNER CAP_FSETID CAP_MKNOD CAP_SETFCAP CAP_SYS_ADMIN CAP_SETPCAP CAP_DAC_OVERRIDE
NoNewPrivileges=yes
-WatchdogSec=1min
+WatchdogSec=3min
KillMode=mixed
diff --git a/units/systemd-journal-remote.service.in b/units/systemd-journal-remote.service.in
index 4a898d62f3..2928a23021 100644
--- a/units/systemd-journal-remote.service.in
+++ b/units/systemd-journal-remote.service.in
@@ -18,7 +18,7 @@ Group=systemd-journal-remote
PrivateTmp=yes
PrivateDevices=yes
PrivateNetwork=yes
-WatchdogSec=10min
+WatchdogSec=3min
[Install]
Also=systemd-journal-remote.socket
diff --git a/units/systemd-journal-upload.service.in b/units/systemd-journal-upload.service.in
index b2e3c769cc..a757673a62 100644
--- a/units/systemd-journal-upload.service.in
+++ b/units/systemd-journal-upload.service.in
@@ -15,7 +15,7 @@ ExecStart=@rootlibexecdir@/systemd-journal-upload \
User=systemd-journal-upload
PrivateTmp=yes
PrivateDevices=yes
-WatchdogSec=20min
+WatchdogSec=3min
# If there are many split up journal files we need a lot of fds to
# access them all and combine
diff --git a/units/systemd-journald.service.in b/units/systemd-journald.service.in
index a3540c65d2..41bfde5be3 100644
--- a/units/systemd-journald.service.in
+++ b/units/systemd-journald.service.in
@@ -22,7 +22,7 @@ RestartSec=0
NotifyAccess=all
StandardOutput=null
CapabilityBoundingSet=CAP_SYS_ADMIN CAP_DAC_OVERRIDE CAP_SYS_PTRACE CAP_SYSLOG CAP_AUDIT_CONTROL CAP_AUDIT_READ CAP_CHOWN CAP_DAC_READ_SEARCH CAP_FOWNER CAP_SETUID CAP_SETGID CAP_MAC_OVERRIDE
-WatchdogSec=1min
+WatchdogSec=3min
FileDescriptorStoreMax=1024
# Increase the default a bit in order to allow many simultaneous
diff --git a/units/systemd-localed.service.in b/units/systemd-localed.service.in
index bfa097844f..9b13f901a3 100644
--- a/units/systemd-localed.service.in
+++ b/units/systemd-localed.service.in
@@ -14,7 +14,7 @@ Documentation=http://www.freedesktop.org/wiki/Software/systemd/localed
ExecStart=@rootlibexecdir@/systemd-localed
BusName=org.freedesktop.locale1
CapabilityBoundingSet=
-WatchdogSec=1min
+WatchdogSec=3min
PrivateTmp=yes
PrivateDevices=yes
PrivateNetwork=yes
diff --git a/units/systemd-logind.service.in b/units/systemd-logind.service.in
index f087e99ce2..ff049134ee 100644
--- a/units/systemd-logind.service.in
+++ b/units/systemd-logind.service.in
@@ -24,7 +24,7 @@ Restart=always
RestartSec=0
BusName=org.freedesktop.login1
CapabilityBoundingSet=CAP_SYS_ADMIN CAP_MAC_ADMIN CAP_AUDIT_CONTROL CAP_CHOWN CAP_KILL CAP_DAC_READ_SEARCH CAP_DAC_OVERRIDE CAP_FOWNER CAP_SYS_TTY_CONFIG
-WatchdogSec=1min
+WatchdogSec=3min
# Increase the default a bit in order to allow many simultaneous
# logins since we keep one fd open per session.
diff --git a/units/systemd-machine-id-commit.service.in b/units/systemd-machine-id-commit.service.in
index cccbf7b626..1f3f5da0f3 100644
--- a/units/systemd-machine-id-commit.service.in
+++ b/units/systemd-machine-id-commit.service.in
@@ -18,5 +18,5 @@ ConditionPathIsMountPoint=/etc/machine-id
[Service]
Type=oneshot
RemainAfterExit=yes
-ExecStart=@rootlibexecdir@/systemd-machine-id-commit
+ExecStart=@rootbindir@/systemd-machine-id-setup --commit
TimeoutSec=30s
diff --git a/units/systemd-machined.service.in b/units/systemd-machined.service.in
index fb1f383cdc..3710c595ca 100644
--- a/units/systemd-machined.service.in
+++ b/units/systemd-machined.service.in
@@ -16,7 +16,7 @@ After=machine.slice
ExecStart=@rootlibexecdir@/systemd-machined
BusName=org.freedesktop.machine1
CapabilityBoundingSet=CAP_KILL CAP_SYS_PTRACE CAP_SYS_ADMIN CAP_SETGID CAP_SYS_CHROOT CAP_DAC_READ_SEARCH CAP_DAC_OVERRIDE CAP_CHOWN CAP_FOWNER CAP_FSETID
-WatchdogSec=1min
+WatchdogSec=3min
# Note that machined cannot be placed in a mount namespace, since it
# needs access to the host's mount namespace in order to implement the
diff --git a/units/systemd-networkd.service.m4.in b/units/systemd-networkd.service.m4.in
index 35be713ade..27d4d58962 100644
--- a/units/systemd-networkd.service.m4.in
+++ b/units/systemd-networkd.service.m4.in
@@ -30,7 +30,7 @@ ExecStart=@rootlibexecdir@/systemd-networkd
CapabilityBoundingSet=CAP_NET_ADMIN CAP_NET_BIND_SERVICE CAP_NET_BROADCAST CAP_NET_RAW CAP_SETUID CAP_SETGID CAP_SETPCAP CAP_CHOWN CAP_DAC_OVERRIDE CAP_FOWNER
ProtectSystem=full
ProtectHome=yes
-WatchdogSec=1min
+WatchdogSec=3min
[Install]
WantedBy=multi-user.target
diff --git a/units/systemd-resolved.service.m4.in b/units/systemd-resolved.service.m4.in
index dce5402458..c674b27ced 100644
--- a/units/systemd-resolved.service.m4.in
+++ b/units/systemd-resolved.service.m4.in
@@ -23,7 +23,7 @@ ExecStart=@rootlibexecdir@/systemd-resolved
CapabilityBoundingSet=CAP_SETUID CAP_SETGID CAP_SETPCAP CAP_CHOWN CAP_DAC_OVERRIDE CAP_FOWNER
ProtectSystem=full
ProtectHome=yes
-WatchdogSec=1min
+WatchdogSec=3min
[Install]
WantedBy=multi-user.target
diff --git a/units/systemd-timedated.service.in b/units/systemd-timedated.service.in
index fe5ccb4601..0c9599db20 100644
--- a/units/systemd-timedated.service.in
+++ b/units/systemd-timedated.service.in
@@ -14,7 +14,7 @@ Documentation=http://www.freedesktop.org/wiki/Software/systemd/timedated
ExecStart=@rootlibexecdir@/systemd-timedated
BusName=org.freedesktop.timedate1
CapabilityBoundingSet=CAP_SYS_TIME
-WatchdogSec=1min
+WatchdogSec=3min
PrivateTmp=yes
ProtectSystem=yes
ProtectHome=yes
diff --git a/units/systemd-timesyncd.service.in b/units/systemd-timesyncd.service.in
index 8219c95a08..a856dad709 100644
--- a/units/systemd-timesyncd.service.in
+++ b/units/systemd-timesyncd.service.in
@@ -27,7 +27,7 @@ PrivateTmp=yes
PrivateDevices=yes
ProtectSystem=full
ProtectHome=yes
-WatchdogSec=1min
+WatchdogSec=3min
[Install]
WantedBy=sysinit.target
diff --git a/units/systemd-udevd.service.in b/units/systemd-udevd.service.in
index e7216d61f2..79f28c87c6 100644
--- a/units/systemd-udevd.service.in
+++ b/units/systemd-udevd.service.in
@@ -23,4 +23,4 @@ RestartSec=0
ExecStart=@rootlibexecdir@/systemd-udevd
MountFlags=slave
KillMode=mixed
-WatchdogSec=1min
+WatchdogSec=3min