Go to:
Gentoo Home
Documentation
Forums
Lists
Bugs
Planet
Store
Wiki
Get Gentoo!
Gentoo's Bugzilla – Attachment 382532 Details for
Bug 519418
sys-apps/systemd-215 - patches from systemd-stable
Home
|
New
–
[Ex]
|
Browse
|
Search
|
Privacy Policy
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
about-eighty-commits-from-systemd-stable-for-v215
20140808-v215-stable.patch (text/plain), 166.16 KB, created by
Ulenrich
on 2014-08-08 15:09:58 UTC
(
hide
)
Description:
about-eighty-commits-from-systemd-stable-for-v215
Filename:
MIME Type:
Creator:
Ulenrich
Created:
2014-08-08 15:09:58 UTC
Size:
166.16 KB
patch
obsolete
>diff --git a/Makefile-man.am b/Makefile-man.am >index 5c289dd..a02ef73 100644 >--- a/Makefile-man.am >+++ b/Makefile-man.am >@@ -63,6 +63,7 @@ MANPAGES += \ > man/systemd-delta.1 \ > man/systemd-detect-virt.1 \ > man/systemd-efi-boot-generator.8 \ >+ man/systemd-escape.1 \ > man/systemd-fsck@.service.8 \ > man/systemd-fstab-generator.8 \ > man/systemd-getty-generator.8 \ >@@ -680,7 +681,8 @@ endif > if ENABLE_COREDUMP > MANPAGES += \ > man/coredump.conf.5 \ >- man/coredumpctl.1 >+ man/coredumpctl.1 \ >+ man/systemd-coredump.8 > MANPAGES_ALIAS += \ > # > >@@ -1594,12 +1596,14 @@ EXTRA_DIST += \ > man/systemd-cat.xml \ > man/systemd-cgls.xml \ > man/systemd-cgtop.xml \ >+ man/systemd-coredump.xml \ > man/systemd-cryptsetup-generator.xml \ > man/systemd-cryptsetup@.service.xml \ > man/systemd-debug-generator.xml \ > man/systemd-delta.xml \ > man/systemd-detect-virt.xml \ > man/systemd-efi-boot-generator.xml \ >+ man/systemd-escape.xml \ > man/systemd-fsck@.service.xml \ > man/systemd-fstab-generator.xml \ > man/systemd-getty-generator.xml \ >diff --git a/Makefile.am b/Makefile.am >index e238cde..764a4fd 100644 >--- a/Makefile.am >+++ b/Makefile.am >@@ -337,7 +337,8 @@ rootbin_PROGRAMS = \ > systemd-notify \ > systemd-ask-password \ > systemd-tty-ask-password-agent \ >- systemd-machine-id-setup >+ systemd-machine-id-setup \ >+ systemd-escape > > bin_PROGRAMS = \ > systemd-cgls \ >@@ -382,7 +383,6 @@ systemgenerator_PROGRAMS = \ > dist_bashcompletion_DATA = \ > shell-completion/bash/busctl \ > shell-completion/bash/journalctl \ >- shell-completion/bash/systemctl \ > shell-completion/bash/systemd-analyze \ > shell-completion/bash/systemd-cat \ > shell-completion/bash/systemd-cgls \ >@@ -394,8 +394,10 @@ dist_bashcompletion_DATA = \ > shell-completion/bash/udevadm \ > shell-completion/bash/kernel-install > >+nodist_bashcompletion_DATA = \ >+ shell-completion/bash/systemctl >+ > dist_zshcompletion_DATA = \ >- shell-completion/zsh/_systemctl \ > shell-completion/zsh/_journalctl \ > shell-completion/zsh/_udevadm \ > shell-completion/zsh/_kernel-install \ >@@ -406,13 +408,23 @@ dist_zshcompletion_DATA = \ > shell-completion/zsh/_systemd-delta \ > shell-completion/zsh/_systemd > >+nodist_zshcompletion_DATA = \ >+ shell-completion/zsh/_systemctl >+ >+EXTRA_DIST += \ >+ shell-completion/bash/systemctl.in \ >+ shell-completion/zsh/_systemctl.in >+ >+CLEANFILES += \ >+ $(nodist_bashcompletion_DATA) \ >+ $(nodist_zshcompletion_DATA) >+ > dist_sysctl_DATA = \ > sysctl.d/50-default.conf > > dist_systemunit_DATA = \ > units/graphical.target \ > units/multi-user.target \ >- units/emergency.service \ > units/emergency.target \ > units/sysinit.target \ > units/basic.target \ >@@ -1712,6 +1724,7 @@ systemd_update_done_SOURCES = \ > > systemd_update_done_LDADD = \ > libsystemd-internal.la \ >+ libsystemd-label.la \ > libsystemd-shared.la > > # ------------------------------------------------------------------------------ >@@ -2079,6 +2092,13 @@ systemd_cgroups_agent_LDADD = \ > libsystemd-shared.la > > # ------------------------------------------------------------------------------ >+systemd_escape_SOURCES = \ >+ src/escape/escape.c >+ >+systemd_escape_LDADD = \ >+ libsystemd-shared.la >+ >+# ----------------------------------------------------------------------------- > systemctl_SOURCES = \ > src/systemctl/systemctl.c > >@@ -3319,16 +3339,6 @@ typelibs_DATA = \ > > CLEANFILES += $(gir_DATA) $(typelibs_DATA) > endif # HAVE_INTROSPECTION >- >-# move lib from $(libdir) to $(rootlibdir) and update devel link, if needed >-libgudev-install-hook: >- libname=libgudev-1.0.so && $(move-to-rootlibdir) >- >-libgudev-uninstall-hook: >- rm -f $(DESTDIR)$(rootlibdir)/libgudev-1.0.so* >- >-INSTALL_EXEC_HOOKS += libgudev-install-hook >-UNINSTALL_EXEC_HOOKS += libgudev-uninstall-hook > endif > > EXTRA_DIST += \ >@@ -4337,7 +4347,7 @@ nodist_systemunit_DATA += \ > units/systemd-timesyncd.service > > GENERAL_ALIASES += \ >- $(systemunitdir)/systemd-timesyncd.service $(pkgsysconfdir)/system/multi-user.target.wants/systemd-timesyncd.service >+ $(systemunitdir)/systemd-timesyncd.service $(pkgsysconfdir)/system/sysinit.target.wants/systemd-timesyncd.service > > EXTRA_DIST += \ > units/systemd-timesyncd.service.in >@@ -5189,6 +5199,9 @@ src/core/macros.%: src/core/macros.%.in > src/%.policy.in: src/%.policy.in.in > $(SED_PROCESS) > >+shell-completion/%: shell-completion/%.in >+ $(SED_PROCESS) >+ > %.rules: %.rules.in > $(SED_PROCESS) > >@@ -5216,7 +5229,7 @@ units/user/%: units/%.m4 > $(AM_V_M4)$(M4) -P $(M4_DEFINES) -DFOR_USER=1 < $< > $@ > > if ENABLE_POLKIT >-dist_polkitpolicy_DATA = \ >+nodist_polkitpolicy_DATA = \ > $(polkitpolicy_files) \ > $(polkitpolicy_in_in_files:.policy.in.in=.policy) > endif >diff --git a/configure.ac b/configure.ac >index ae88382..8925eb5 100644 >--- a/configure.ac >+++ b/configure.ac >@@ -310,7 +310,9 @@ AC_CHECK_DECLS([gettid, pivot_root, name_to_handle_at, setns, LO_FLAGS_PARTSCAN] > #include <linux/loop.h> > ]]) > >-AC_CHECK_DECLS([IFLA_PHYS_PORT_ID, >+AC_CHECK_DECLS([IFLA_MACVLAN_FLAGS, >+ IFLA_VTI_REMOTE, >+ IFLA_PHYS_PORT_ID, > IFLA_BOND_AD_INFO, > IFLA_VLAN_PROTOCOL, > IFLA_VXLAN_LOCAL6, >diff --git a/man/coredumpctl.xml b/man/coredumpctl.xml >index 73d1b84..327ef6e 100644 >--- a/man/coredumpctl.xml >+++ b/man/coredumpctl.xml >@@ -210,6 +210,8 @@ > <refsect1> > <title>See Also</title> > <para> >+ <citerefentry><refentrytitle>systemd-coredump</refentrytitle><manvolnum>8</manvolnum></citerefentry>, >+ <citerefentry><refentrytitle>coredump.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>, > <citerefentry><refentrytitle>systemd-journald.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>, > <citerefentry><refentrytitle>gdb</refentrytitle><manvolnum>1</manvolnum></citerefentry> > </para> >diff --git a/man/crypttab.xml b/man/crypttab.xml >index 9dbf154..d658a6f 100644 >--- a/man/crypttab.xml >+++ b/man/crypttab.xml >@@ -319,6 +319,21 @@ > </varlistentry> > > <varlistentry> >+ <term><option>x-systemd.device-timeout=</option></term> >+ >+ <listitem><para>Specifies how long >+ systemd should wait for a device to >+ show up before giving up on the >+ entry. The argument is a time in >+ seconds or explicitly specifified >+ units of <literal>s</literal>, >+ <literal>min</literal>, >+ <literal>h</literal>, >+ <literal>ms</literal>. >+ </para></listitem> >+ </varlistentry> >+ >+ <varlistentry> > <term><option>tmp</option></term> > > <listitem><para>The encrypted block device will >diff --git a/man/file-hierarchy.xml b/man/file-hierarchy.xml >index ed6e0e9..408042e 100644 >--- a/man/file-hierarchy.xml >+++ b/man/file-hierarchy.xml >@@ -190,7 +190,9 @@ > should prefer using the directory > specified in it over directly > referencing >- <filename>/tmp</filename> (see <citerefentry><refentrytitle>environ</refentrytitle><manvolnum>7</manvolnum></citerefentry> for details).</para></listitem> >+ <filename>/tmp</filename> (see <citerefentry><refentrytitle>environ</refentrytitle><manvolnum>7</manvolnum></citerefentry> >+ and >+ <ulink url="http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap08.html#tag_08_03">IEEE Std 1003.1</ulink> for details).</para></listitem> > </varlistentry> > > </variablelist> >@@ -461,7 +463,8 @@ > set they should prefer using the > directory specified in it over > directly referencing >- <filename>/var/tmp</filename> (see <citerefentry><refentrytitle>environ</refentrytitle><manvolnum>7</manvolnum></citerefentry> for details). >+ <filename>/var/tmp</filename> (see <citerefentry><refentrytitle>environ</refentrytitle><manvolnum>7</manvolnum></citerefentry> >+ for details). > </para></listitem> > </varlistentry> > >diff --git a/man/hostnamectl.xml b/man/hostnamectl.xml >index 71973fd..13e5bd5 100644 >--- a/man/hostnamectl.xml >+++ b/man/hostnamectl.xml >@@ -102,14 +102,6 @@ > </varlistentry> > > <varlistentry> >- <term><option>-P</option></term> >- <term><option>--privileged</option></term> >- >- <listitem><para>Acquire privileges via PolicyKit >- before executing the operation.</para></listitem> >- </varlistentry> >- >- <varlistentry> > <term><option>--static</option></term> > <term><option>--transient</option></term> > <term><option>--pretty</option></term> >@@ -149,13 +141,14 @@ > </varlistentry> > > <varlistentry> >- <term><command>set-hostname [NAME]</command></term> >+ <term><command>set-hostname <replaceable>NAME</replaceable></command></term> > > <listitem><para>Set the system >- hostname. By default, this will alter >- the pretty, the static, and the >- transient hostname alike; however, if >- one or more of >+ hostname to >+ <replaceable>NAME</replaceable>. By >+ default, this will alter the pretty, >+ the static, and the transient hostname >+ alike; however, if one or more of > <option>--static</option>, > <option>--transient</option>, > <option>--pretty</option> are used, >@@ -176,54 +169,61 @@ > the hostname string is not done if > only the transient and/or static host > names are set, and the pretty host >- name is left untouched. Pass the empty >- string <literal></literal> as the >- hostname to reset the selected >- hostnames to their default (usually >+ name is left untouched.</para> >+ >+ <para>Pass the empty string >+ <literal></literal> as the hostname to >+ reset the selected hostnames to their >+ default (usually > <literal>localhost</literal>).</para></listitem> > </varlistentry> > > <varlistentry> >- <term><command>set-icon-name [NAME]</command></term> >+ <term><command>set-icon-name <replaceable>NAME</replaceable></command></term> > > <listitem><para>Set the system icon >- name. The icon name is used by some >- graphical applications to visualize >- this host. The icon name should follow >- the <ulink >+ name to >+ <replaceable>NAME</replaceable>. The >+ icon name is used by some graphical >+ applications to visualize this host. >+ The icon name should follow the <ulink > url="http://standards.freedesktop.org/icon-naming-spec/icon-naming-spec-latest.html">Icon >- Naming Specification</ulink>. Pass an >- empty string to this operation to >- reset the icon name to the default >- value, which is determined from chassis >- type (see below) and possibly other >+ Naming Specification</ulink>.</para> >+ >+ <para>Pass an empty string to reset >+ the icon name to the default value, >+ which is determined from chassis type >+ (see below) and possibly other > parameters.</para></listitem> > </varlistentry> > > <varlistentry> >- <term><command>set-chassis [TYPE]</command></term> >+ <term><command>set-chassis <replaceable>TYPE</replaceable></command></term> > >- <listitem><para>Set the chassis >- type. The chassis type is used by some >+ <listitem><para>Set the chassis type >+ to <replaceable>TYPE</replaceable>. >+ The chassis type is used by some > graphical applications to visualize >- the host or alter user >- interaction. Currently, the following >- chassis types are defined: >+ the host or alter user interaction. >+ Currently, the following chassis types >+ are defined: > <literal>desktop</literal>, > <literal>laptop</literal>, > <literal>server</literal>, > <literal>tablet</literal>, >- <literal>handset</literal>, as well as >+ <literal>handset</literal>, >+ <literal>watch</literal>, as well as > the special chassis types > <literal>vm</literal> and > <literal>container</literal> for > virtualized systems that lack an >- immediate physical chassis. Pass an >- empty string to this operation to >- reset the chassis type to the default >- value which is determined from the >- firmware and possibly other >- parameters.</para></listitem> >+ immediate physical chassis.</para> >+ >+ <para>Pass an empty string to reset >+ the chassis type to the default value >+ which is determined from the firmware >+ and possibly other parameters.</para> >+ </listitem> > </varlistentry> > > </variablelist> >diff --git a/man/journalctl.xml b/man/journalctl.xml >index 78fc6f6..de7741c 100644 >--- a/man/journalctl.xml >+++ b/man/journalctl.xml >@@ -908,6 +908,7 @@ > <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>, > <citerefentry><refentrytitle>systemd-journald.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>, > <citerefentry><refentrytitle>systemctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>, >+ <citerefentry><refentrytitle>coredumpctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>, > <citerefentry><refentrytitle>systemd.journal-fields</refentrytitle><manvolnum>7</manvolnum></citerefentry>, > <citerefentry><refentrytitle>journald.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry> > </para> >diff --git a/man/localectl.xml b/man/localectl.xml >index c2e79a2..9c32c79 100644 >--- a/man/localectl.xml >+++ b/man/localectl.xml >@@ -90,14 +90,6 @@ > </varlistentry> > > <varlistentry> >- <term><option>-P</option></term> >- <term><option>--privileged</option></term> >- >- <listitem><para>Acquire privileges via PolicyKit >- before executing the operation.</para></listitem> >- </varlistentry> >- >- <varlistentry> > <term><option>--no-convert</option></term> > > <listitem><para>If >diff --git a/man/machine-info.xml b/man/machine-info.xml >index 7448e68..244e9b6 100644 >--- a/man/machine-info.xml >+++ b/man/machine-info.xml >@@ -138,7 +138,8 @@ > <literal>laptop</literal>, > <literal>server</literal>, > <literal>tablet</literal>, >- <literal>handset</literal>, as well as >+ <literal>handset</literal>, >+ <literal>watch</literal>, as well as > the special chassis types > <literal>vm</literal> and > <literal>container</literal> for >diff --git a/man/sd_journal_get_cutoff_realtime_usec.xml b/man/sd_journal_get_cutoff_realtime_usec.xml >index 6df4b26..ef987d8 100644 >--- a/man/sd_journal_get_cutoff_realtime_usec.xml >+++ b/man/sd_journal_get_cutoff_realtime_usec.xml >@@ -74,25 +74,29 @@ > <title>Description</title> > > <para><function>sd_journal_get_cutoff_realtime_usec()</function> >- gets the realtime (wallclock) timestamps of the first >- and last entries accessible in the journal. It takes >- three arguments: the journal context object and two >- pointers to 64-bit unsigned integers to store the >- timestamps in. The timestamps are in microseconds >- since the epoch, >+ retrieves the realtime (wallclock) timestamps of the >+ first and last entries accessible in the journal. It >+ takes three arguments: the journal context object >+ <parameter>j</parameter> and two pointers >+ <parameter>from</parameter> and >+ <parameter>to</parameter> pointing at 64-bit unsigned >+ integers to store the timestamps in. The timestamps >+ are in microseconds since the epoch, > i.e. <constant>CLOCK_REALTIME</constant>. Either one > of the two timestamp arguments may be passed as > <constant>NULL</constant> in case the timestamp is not > needed, but not both.</para> > > <para><function>sd_journal_get_cutoff_monotonic_usec()</function> >- gets the monotonic timestamps of the first and last >- entries accessible in the journal. It takes three >- arguments: the journal context object, a 128-bit >- identifier for the boot, and two pointers to 64-bit >- unsigned integers to store the timestamps. The >- timestamps are in microseconds since boot-up of the >- specific boot, >+ retrieves the monotonic timestamps of the first and >+ last entries accessible in the journal. It takes three >+ arguments: the journal context object >+ <parameter>j</parameter>, a 128-bit identifier for the >+ boot <parameter>boot_id</parameter>, and two pointers >+ to 64-bit unsigned integers to store the timestamps, >+ <parameter>from</parameter> and >+ <parameter>to</parameter>. The timestamps are in >+ microseconds since boot-up of the specific boot, > i.e. <constant>CLOCK_MONOTONIC</constant>. Since the > monotonic clock begins new with every reboot it only > defines a well-defined point in time when used >@@ -113,6 +117,12 @@ > <function>sd_journal_get_cutoff_monotonic_usec()</function> > return 1 on success, 0 if not suitable entries are in > the journal or a negative errno-style error code.</para> >+ >+ <para>Locations pointed to by parameters >+ <parameter>from</parameter> and >+ <parameter>to</parameter> will be set only if the >+ return value is positive, and obviously, the >+ parameters are non-null.</para> > </refsect1> > > <refsect1> >diff --git a/man/systemd-coredump.xml b/man/systemd-coredump.xml >new file mode 100644 >index 0000000..b83b278 >--- /dev/null >+++ b/man/systemd-coredump.xml >@@ -0,0 +1,105 @@ >+<?xml version='1.0'?> <!--*-nxml-*--> >+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" >+ "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd"> >+ >+<!-- >+ This file is part of systemd. >+ >+ Copyright 2014 Zbigniew JÄdrzejewski-Szmek >+ >+ systemd is free software; you can redistribute it and/or modify it >+ under the terms of the GNU Lesser General Public License as published by >+ the Free Software Foundation; either version 2.1 of the License, or >+ (at your option) any later version. >+ >+ systemd is distributed in the hope that it will be useful, but >+ WITHOUT ANY WARRANTY; without even the implied warranty of >+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU >+ Lesser General Public License for more details. >+ >+ You should have received a copy of the GNU Lesser General Public License >+ along with systemd; If not, see <http://www.gnu.org/licenses/>. >+--> >+ >+<refentry id="systemd-coredump" conditional='ENABLE_COREDUMP' >+ xmlns:xi="http://www.w3.org/2001/XInclude"> >+ >+ <refentryinfo> >+ <title>systemd-coredump</title> >+ <productname>systemd</productname> >+ >+ <authorgroup> >+ <author> >+ <contrib>Developer</contrib> >+ <firstname>Lennart</firstname> >+ <surname>Poettering</surname> >+ <email>lennart@poettering.net</email> >+ </author> >+ </authorgroup> >+ </refentryinfo> >+ >+ <refmeta> >+ <refentrytitle>systemd-coredump</refentrytitle> >+ <manvolnum>8</manvolnum> >+ </refmeta> >+ >+ <refnamediv> >+ <refname>systemd-coredump</refname> >+ <refpurpose>Log and store core dumps</refpurpose> >+ </refnamediv> >+ >+ <refsynopsisdiv> >+ <para><filename>/usr/lib/systemd/systemd-coredump</filename></para> >+ </refsynopsisdiv> >+ >+ <refsect1> >+ <title>Description</title> >+ >+ <para><command>systemd-coredump</command> can be used as a helper >+ binary by the kernel when a user space program receives a fatal >+ signal and dumps core. For it to be used in this capacity, it must >+ be specified by the >+ <varname>kernel.core_pattern</varname> <citerefentry project='man-pages'><refentrytitle>sysctl</refentrytitle><manvolnum>8</manvolnum></citerefentry> >+ setting. Systemd installs >+ <filename>/usr/lib/sysctl.d/50-coredump.conf</filename> which >+ configures <varname>kernel.core_pattern</varname> to invoke >+ <command>systemd-coredump</command>. This file may be masked or >+ overriden to use a different setting following normal >+ <citerefentry><refentrytitle>sysctl.d</refentrytitle><manvolnum>5</manvolnum></citerefentry> rules.</para> >+ >+ <para>The behaviour of a specific program upon reception of a >+ signal is governed by a few factors which are described in detail >+ in <citerefentry project='man-pages'><refentrytitle>core</refentrytitle><manvolnum>5</manvolnum></citerefentry>. >+ In particular, the coredump will only be processed when the >+ related resource limits are high enough. For programs started by >+ <command>systemd</command> those may be set using >+ <varname>LimitCore=</varname> (see >+ <citerefentry><refentrytitle>systemd.exec</refentrytitle><manvolnum>5</manvolnum></citerefentry>). >+ </para> >+ >+ <para><command>systemd-coredump</command> will log the coredump >+ including a backtrace if possible, and store the core (contents of >+ process' memory contents) in an external file on disk in >+ <filename>/var/lib/systemd/coredump</filename>, or directly in >+ the journal. This behaviour may be modified using >+ <citerefentry><refentrytitle>coredump.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>.</para> >+ >+ <para>Apart from the >+ <citerefentry><refentrytitle>journalctl</refentrytitle><manvolnum>1</manvolnum></citerefentry> >+ log viewer, >+ <citerefentry><refentrytitle>coredumpctl</refentrytitle><manvolnum>1</manvolnum></citerefentry> >+ may be used to list and extract coredumps.</para> >+ </refsect1> >+ >+ <refsect1> >+ <title>See Also</title> >+ <para> >+ <citerefentry><refentrytitle>coredump.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>, >+ <citerefentry><refentrytitle>coredumpctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>, >+ <citerefentry><refentrytitle>systemd-journald.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>, >+ <citerefentry project='man-pages'><refentrytitle>core</refentrytitle><manvolnum>5</manvolnum></citerefentry>, >+ <citerefentry><refentrytitle>sysctl.d</refentrytitle><manvolnum>5</manvolnum></citerefentry>, >+ <citerefentry><refentrytitle>systemd-sysctl.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>. >+ </para> >+ </refsect1> >+</refentry> >diff --git a/man/systemd-escape.xml b/man/systemd-escape.xml >new file mode 100644 >index 0000000..b2a4a9c >--- /dev/null >+++ b/man/systemd-escape.xml >@@ -0,0 +1,193 @@ >+<?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 Lennart Poettering >+ >+ 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-escape" >+ xmlns:xi="http://www.w3.org/2001/XInclude"> >+ >+ <refentryinfo> >+ <title>systemd-escape</title> >+ <productname>systemd</productname> >+ >+ <authorgroup> >+ <author> >+ <contrib>Developer</contrib> >+ <firstname>Lennart</firstname> >+ <surname>Poettering</surname> >+ <email>lennart@poettering.net</email> >+ </author> >+ </authorgroup> >+ </refentryinfo> >+ >+ <refmeta> >+ <refentrytitle>systemd-escape</refentrytitle> >+ <manvolnum>1</manvolnum> >+ </refmeta> >+ >+ <refnamediv> >+ <refname>systemd-escape</refname> >+ <refpurpose>Escape strings for usage in system unit names</refpurpose> >+ </refnamediv> >+ >+ <refsynopsisdiv> >+ <cmdsynopsis> >+ <command>systemd-escape <arg choice="opt" rep="repeat">OPTIONS</arg> <arg choice="opt" rep="repeat">STRING</arg></command> >+ </cmdsynopsis> >+ </refsynopsisdiv> >+ >+ <refsect1> >+ <title>Description</title> >+ >+ <para><command>systemd-escape</command> may be used to >+ escape strings for inclusion in systemd unit >+ names. The command may be used to escape and to undo >+ escaping of strings.</para> >+ >+ <para>The command takes any number of strings on the >+ command line, and will process them individually, one >+ after the other. It will output them separated by >+ spaces to stdout.</para> >+ >+ <para>By default this command will escape the strings >+ passed, unless <option>--unescape</option> is passed >+ which results in the inverse operation being >+ applied. If <option>--mangle</option> a special mode >+ of escaping is applied instead, which assumes a string >+ to be already escaped but will escape everything that >+ appears obviously non-escaped.</para> >+ </refsect1> >+ >+ <refsect1> >+ <title>Options</title> >+ >+ <para>The following options are understood:</para> >+ >+ <variablelist> >+ <varlistentry> >+ <term><option>--suffix=</option></term> >+ >+ <listitem><para>Appends the specified >+ unit type suffix to the escaped >+ string. Takes one of the unit types >+ supported by systemd, such as >+ <literal>.service</literal> or >+ <literal>.mount</literal>. May not be >+ used in conjunction with >+ <option>--template=</option>, >+ <option>--unescape</option> or >+ <option>--mangle</option>.</para></listitem> >+ </varlistentry> >+ >+ <varlistentry> >+ <term><option>--template=</option></term> >+ >+ <listitem><para>Inserts the escaped >+ strings in a unit name template. Takes >+ a unit name template such as >+ <filename>foobar@.service</filename> >+ May not be used in conjunction with >+ <option>--suffix=</option>, >+ <option>--unescape</option> or >+ <option>--mangle</option>.</para></listitem> >+ </varlistentry> >+ >+ <varlistentry> >+ <term><option>--path</option></term> >+ <term><option>-p</option></term> >+ >+ <listitem><para>When escaping or >+ unescaping a string, assume it refers >+ to a file system path. This enables >+ special processing of the initial >+ <literal>/</literal> of the >+ path.</para></listitem> >+ </varlistentry> >+ >+ <varlistentry> >+ <term><option>--unescape</option></term> >+ >+ <listitem><para>Instead of escaping >+ the specified strings, undo the >+ escaping, reversing the operation. May >+ not be used in conjunction with >+ <option>--suffix=</option>, >+ <option>--template=</option> or >+ <option>--mangle</option>.</para></listitem> >+ </varlistentry> >+ >+ <varlistentry> >+ <term><option>--mangle</option></term> >+ >+ <listitem><para>Like >+ <option>--escape</option>, but only >+ escape characters that are obviously >+ not escaped yet, and possibly >+ automatically append an appropriate >+ unit type suffix to the string. May >+ not be used in conjunction with >+ <option>--suffix=</option>, >+ <option>--template=</option> or >+ <option>--unescape</option>.</para></listitem> >+ </varlistentry> >+ >+ <xi:include href="standard-options.xml" xpointer="help" /> >+ <xi:include href="standard-options.xml" xpointer="version" /> >+ </variablelist> >+ >+ </refsect1> >+ >+ <refsect1> >+ <title>Examples</title> >+ >+ <para>Escape a single string:</para> >+ <programlisting>$ systemd-escape 'Hallöchen, Meister' >+Hall\xc3\xb6chen\x2c\x20Meister</programlisting> >+ >+ <para>To undo escaping on a single string:</para> >+ <programlisting>$ systemd-escape -u 'Hall\xc3\xb6chen\x2c\x20Meister' >+Hallöchen, Meister</programlisting> >+ >+ <para>To generate the mount unit for a path:</para> >+ <programlisting>$ systemd-escape -p --suffix=mount "/tmp//waldi/foobar/" >+tmp-waldi-foobar.mount</programlisting> >+ >+ <para>To generate instance names of three strings</para> >+ <programlisting>$ systemd-escape --template=systemd-nspawn@.service 'My Container 1' 'containerb' 'container/III' >+systemd-nspawn@My\x20Container\x201.service systemd-nspawn@containerb.service systemd-nspawn@container-III.service</programlisting> >+ </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>systemctl</refentrytitle><manvolnum>1</manvolnum></citerefentry> >+ </para> >+ </refsect1> >+ >+</refentry> >diff --git a/man/systemd-journald.service.xml b/man/systemd-journald.service.xml >index 7ac73ed..eb16118 100644 >--- a/man/systemd-journald.service.xml >+++ b/man/systemd-journald.service.xml >@@ -248,6 +248,7 @@ > <citerefentry><refentrytitle>journald.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>, > <citerefentry><refentrytitle>systemd.journal-fields</refentrytitle><manvolnum>7</manvolnum></citerefentry>, > <citerefentry><refentrytitle>sd-journal</refentrytitle><manvolnum>3</manvolnum></citerefentry>, >+ <citerefentry><refentrytitle>systemd-coredump</refentrytitle><manvolnum>8</manvolnum></citerefentry>, > <citerefentry><refentrytitle>setfacl</refentrytitle><manvolnum>1</manvolnum></citerefentry>, > <command>pydoc systemd.journal</command>. > </para> >diff --git a/man/systemd.netdev.xml b/man/systemd.netdev.xml >index c90bd8f..347f80e 100644 >--- a/man/systemd.netdev.xml >+++ b/man/systemd.netdev.xml >@@ -60,7 +60,10 @@ > > <para>Virtual Network Device files must have the extension > <filename>.netdev</filename>; other extensions are ignored. Virtual >- network devices are created as soon as networkd is started.</para> >+ network devices are created as soon as networkd is started. If a netdev >+ with the specified name already exists, networkd will use that as-is >+ rather than create its own. Note that the settings of the pre-existing >+ netdev will not be changed by networkd.</para> > > <para>The <filename>.netdev</filename> files are read from the files located in the > system network directory <filename>/usr/lib/systemd/network</filename>, >@@ -163,7 +166,8 @@ > <literal>macvlan</literal>, <literal>vxlan</literal>, > <literal>ipip</literal>, <literal>gre</literal>, > <literal>sit</literal>, <literal>vti</literal>, >- <literal>veth</literal>, and <literal>dummy</literal> >+ <literal>veth</literal>, <literal>tun</literal>, >+ <literal>tap</literal> and <literal>dummy</literal> > are supported. This option is compulsory.</para> > </listitem> > </varlistentry> >diff --git a/man/systemd.time.xml b/man/systemd.time.xml >index 0706cdf..02431a5 100644 >--- a/man/systemd.time.xml >+++ b/man/systemd.time.xml >@@ -243,12 +243,16 @@ > > <para>The special expressions > <literal>hourly</literal>, <literal>daily</literal>, >- <literal>monthly</literal> and <literal>weekly</literal> >- may be used as calendar events which refer to >- <literal>*-*-* *:00:00</literal>, <literal>*-*-* >- 00:00:00</literal>, <literal>*-*-01 00:00:00</literal> and >- <literal>Mon *-*-* 00:00:00</literal>, >- respectively.</para> >+ <literal>monthly</literal>, <literal>weekly</literal>, >+ and <literal>yearly</literal> or >+ <literal>annually</literal> may be used as calendar >+ events which refer to >+ <literal>*-*-* *:00:00</literal>, >+ <literal>*-*-* 00:00:00</literal>, >+ <literal>*-*-01 00:00:00</literal>, >+ <literal>Mon *-*-* 00:00:00</literal>, and >+ <literal>*-01-01 00:00:00</literal> respectively. >+ </para> > > <para>Examples for valid timestamps and their > normalized form:</para> >@@ -277,6 +281,8 @@ Wed-Sat,Tue 12-10-15 1:2:3 â Tue-Sat 2012-10-15 01:02:03 > daily â *-*-* 00:00:00 > monthly â *-*-01 00:00:00 > weekly â Mon *-*-* 00:00:00 >+ yearly â *-01-01 00:00:00 >+ annually â *-01-01 00:00:00 > *:2/3 â *-*-* *:02/3:00</programlisting> > > <para>Calendar events are used by timer units, see >diff --git a/man/systemd.unit.xml b/man/systemd.unit.xml >index 960fb90..e66be4e 100644 >--- a/man/systemd.unit.xml >+++ b/man/systemd.unit.xml >@@ -74,6 +74,8 @@ > <filename>$HOME/.config/systemd/user/*</filename> > <filename>/etc/systemd/user/*</filename> > <filename>/run/systemd/user/*</filename> >+<filename>$XDG_DATA_HOME/systemd/user/*</filename> >+<filename>$HOME/.local/share/systemd/user/*</filename> > <filename>/usr/lib/systemd/user/*</filename> > <filename>...</filename> > </literallayout></para> >@@ -339,8 +341,16 @@ > <entry>Runtime units</entry> > </row> > <row> >+ <entry><filename>$XDG_DATA_HOME/systemd/user</filename></entry> >+ <entry>Units of packages that have been installed in the home directory (only used when $XDG_DATA_HOME is set)</entry> >+ </row> >+ <row> >+ <entry><filename>$HOME/.local/share/systemd/user</filename></entry> >+ <entry>Units of packages that have been installed in the home directory (only used when $XDG_DATA_HOME is not set)</entry> >+ </row> >+ <row> > <entry><filename>/usr/lib/systemd/user</filename></entry> >- <entry>Units of installed packages</entry> >+ <entry>Units of packages that have been installed system-wide</entry> > </row> > </tbody> > </tgroup> >@@ -931,7 +941,9 @@ > <varname>x86</varname>, > <varname>x86-64</varname>, > <varname>ppc</varname>, >+ <varname>ppc-le</varname>, > <varname>ppc64</varname>, >+ <varname>ppc64-le</varname>, > <varname>ia64</varname>, > <varname>parisc</varname>, > <varname>parisc64</varname>, >@@ -940,7 +952,9 @@ > <varname>sparc</varname>, > <varname>sparc64</varname>, > <varname>mips</varname>, >+ <varname>mips-le</varname>, > <varname>mips64</varname>, >+ <varname>mips64-le</varname>, > <varname>alpha</varname>, > <varname>arm</varname>, > <varname>arm-be</varname>, >@@ -948,7 +962,9 @@ > <varname>arm64-be</varname>, > <varname>sh</varname>, > <varname>sh64</varname>, >- <varname>m86k</varname> to test >+ <varname>m86k</varname>, >+ <varname>tilegx</varname>, >+ <varname>cris</varname> to test > against a specific architecture. The > architecture is determined from the > information returned by >@@ -979,12 +995,12 @@ > virtualization solution, or one of > <varname>qemu</varname>, > <varname>kvm</varname>, >+ <varname>zvm</varname>, > <varname>vmware</varname>, > <varname>microsoft</varname>, > <varname>oracle</varname>, > <varname>xen</varname>, > <varname>bochs</varname>, >- <varname>chroot</varname>, > <varname>uml</varname>, > <varname>openvz</varname>, > <varname>lxc</varname>, >diff --git a/man/sysusers.d.xml b/man/sysusers.d.xml >index 549b3f6..1e079b2 100644 >--- a/man/sysusers.d.xml >+++ b/man/sysusers.d.xml >@@ -53,32 +53,28 @@ > <title>Description</title> > > <para><command>systemd-sysusers</command> uses the >- files from <filename>/usr/lib/sysusers.d/</filename> >+ files from <filename>sysusers.d</filename> directory > to create system users and groups at package >- installation or boot time. This tool may be used for >- allocating system users and groups only, it is not >+ installation or boot time. This tool may be used to >+ allocate system users and groups only, it is not > useful for creating non-system users and groups, as it >- accessed <filename>/etc/passwd</filename> and >+ accesses <filename>/etc/passwd</filename> and > <filename>/etc/group</filename> directly, bypassing >- any more complex user database, for example any >+ any more complex user databases, for example any > database involving NIS or LDAP.</para> >- > </refsect1> > > <refsect1> >- <title>File Format</title> >- >- <para>Each file shall be named in the style of >- <filename><replaceable>package</replaceable>.conf</filename>.</para> >+ <title>Configuration Format</title> > >- <para>All files are sorted by their filename in >- lexicographic order, regardless of which of the >- directories they reside in. If multiple files specify >- the same user or group, the entry in the file with the >- lexicographically earliest name will be applied, all >- all other conflicting entries will be logged as >- errors. Users and groups are >- processed in the order they are listed.</para> >+ <para>Each configuration file shall be named in the >+ style of >+ <filename><replaceable>package</replaceable>.conf</filename> >+ or >+ <filename><replaceable>package</replaceable>-<replaceable>part</replaceable>.conf</filename>. >+ The second variant should be used when it is desirable >+ to make it easy to override just this part of >+ configuration.</para> > > <para>The file format is one line per user or group > containing name, ID and GECOS field description:</para> >@@ -106,7 +102,7 @@ m authd input</programlisting> > group will be set to the group > bearing the same name. The > user's shell will be set to >- <filename>/sbin/login</filename>, >+ <filename>/sbin/nologin</filename>, > the home directory to > <filename>/</filename>. The > account will be created >@@ -142,7 +138,7 @@ m authd input</programlisting> > <title>Name</title> > > <para>The name field specifies the user or >- group name. It should be be shorter than 256 >+ group name. It should be be shorter than 31 > characters and avoid any non-ASCII characters, > and not begin with a numeric character. It is > strongly recommended to pick user and group >@@ -193,10 +189,39 @@ m authd input</programlisting> > </refsect1> > > <refsect1> >+ <title>Overriding vendor configuration</title> >+ >+ <para>Note that <command>systemd-sysusers</command> >+ will do nothing if the specified users or groups >+ already exist, so normally there no reason to override >+ <filename>sysusers.d</filename> vendor configuration, >+ except to block certain users or groups from being >+ created.</para> >+ >+ <para>Files in <filename>/etc/sysusers.d</filename> >+ override files with the same name in >+ <filename>/usr/lib/sysusers.d</filename> and >+ <filename>/run/sysusers.d</filename>. Files in >+ <filename>/run/sysusers.d</filename> override files >+ with the same name in >+ <filename>/usr/lib/sysusers.d</filename>. The scheme is the same as for >+ <citerefentry><refentrytitle>tmpfiles.d</refentrytitle><manvolnum>5</manvolnum></citerefentry>, >+ except for the directory name.</para> >+ >+ <para>If the administrator wants to disable a >+ configuration file supplied by the vendor, the >+ recommended way is to place a symlink to >+ <filename>/dev/null</filename> in >+ <filename>/etc/sysusers.d/</filename> bearing the >+ same filename.</para> >+ </refsect1> >+ >+ <refsect1> > <title>See Also</title> > <para> > <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>, >- <citerefentry><refentrytitle>systemd-sysusers</refentrytitle><manvolnum>8</manvolnum></citerefentry> >+ <citerefentry><refentrytitle>systemd-sysusers</refentrytitle><manvolnum>8</manvolnum></citerefentry>, >+ <citerefentry><refentrytitle>tmpfiles.d</refentrytitle><manvolnum>5</manvolnum></citerefentry> > </para> > </refsect1> > >diff --git a/rules/99-systemd.rules.in b/rules/99-systemd.rules.in >index db72373..c3ef81b 100644 >--- a/rules/99-systemd.rules.in >+++ b/rules/99-systemd.rules.in >@@ -43,7 +43,7 @@ SUBSYSTEM=="net", KERNEL!="lo", TAG+="systemd", ENV{SYSTEMD_ALIAS}+="/sys/subsys > SUBSYSTEM=="bluetooth", TAG+="systemd", ENV{SYSTEMD_ALIAS}+="/sys/subsystem/bluetooth/devices/%k" > > SUBSYSTEM=="bluetooth", TAG+="systemd", ENV{SYSTEMD_WANTS}+="bluetooth.target" >-ENV{ID_SMARTCARD_READER}=="*?", TAG+="systemd", ENV{SYSTEMD_WANTS}+="smartcard.target" >+ENV{ID_SMARTCARD_READER}=="?*", TAG+="systemd", ENV{SYSTEMD_WANTS}+="smartcard.target" > SUBSYSTEM=="sound", KERNEL=="card*", TAG+="systemd", ENV{SYSTEMD_WANTS}+="sound.target" > > SUBSYSTEM=="printer", TAG+="systemd", ENV{SYSTEMD_WANTS}+="printer.target" >diff --git a/shell-completion/bash/.gitignore b/shell-completion/bash/.gitignore >new file mode 100644 >index 0000000..016e09d >--- /dev/null >+++ b/shell-completion/bash/.gitignore >@@ -0,0 +1 @@ >+/systemctl >diff --git a/shell-completion/bash/hostnamectl b/shell-completion/bash/hostnamectl >index 9c75da9..22f8f06 100644 >--- a/shell-completion/bash/hostnamectl >+++ b/shell-completion/bash/hostnamectl >@@ -39,6 +39,7 @@ _hostnamectl() { > [STANDALONE]='status' > [ICONS]='set-icon-name' > [NAME]='set-hostname' >+ [CHASSIS]='set-chassis' > ) > > for ((i=0; i < COMP_CWORD; i++)); do >@@ -50,6 +51,8 @@ _hostnamectl() { > > if [[ -z $verb ]]; then > comps=${VERBS[*]} >+ elif __contains_word "$verb" ${VERBS[CHASSIS]}; then >+ comps='desktop laptop server tablet handset watch vm container' > elif __contains_word "$verb" ${VERBS[STANDALONE]} ${VERBS[ICONS]} ${VERBS[NAME]}; then > comps='' > fi >diff --git a/shell-completion/bash/journalctl b/shell-completion/bash/journalctl >index e4b2f4a..14dcd22 100644 >--- a/shell-completion/bash/journalctl >+++ b/shell-completion/bash/journalctl >@@ -35,6 +35,8 @@ __journal_fields=(MESSAGE{,_ID} PRIORITY CODE_{FILE,LINE,FUNC} > _UDEV_{SYSNAME,DEVNODE,DEVLINK} > __CURSOR __{REALTIME,MONOTONIC}_TIMESTAMP) > >+__syslog_priorities=(emerg alert crit err warning notice info debug) >+ > _journalctl() { > local field_vals= cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]} > local -A OPTS=( >@@ -44,8 +46,8 @@ _journalctl() { > --no-tail -q --quiet --setup-keys --this-boot --verify > --version --list-catalog --update-catalog --list-boots' > [ARG]='-b --boot --this-boot -D --directory --file -F --field >- -o --output -u --unit --user-unit' >- [ARGUNKNOWN]='-c --cursor --interval -n --lines -p --priority --since --until >+ -o --output -u --unit --user-unit -p --priority' >+ [ARGUNKNOWN]='-c --cursor --interval -n --lines --since --until > --verify-key' > ) > >@@ -68,6 +70,9 @@ _journalctl() { > --field|-F) > comps=${__journal_fields[*]} > ;; >+ --priority|-p) >+ comps=${__syslog_priorities[*]} >+ ;; > --unit|-u) > comps=$(journalctl -F '_SYSTEMD_UNIT' 2>/dev/null) > ;; >diff --git a/shell-completion/bash/systemctl b/shell-completion/bash/systemctl >deleted file mode 100644 >index e1c8420..0000000 >--- a/shell-completion/bash/systemctl >+++ /dev/null >@@ -1,226 +0,0 @@ >-# systemctl(1) completion -*- shell-script -*- >-# >-# This file is part of systemd. >-# >-# Copyright 2010 Ran Benita >-# >-# 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 >-# 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/>. >- >-__systemctl() { >- local mode=$1; shift 1 >- systemctl $mode --full --no-legend "$@" >-} >- >-__systemd_properties() { >- local mode=$1 >- { __systemctl -a $mode show; >- systemd --dump-configuration-items; } | >- while IFS='=' read -r key value; do >- [[ $value ]] && echo "$key" >- done >-} >- >-__contains_word () { >- local w word=$1; shift >- for w in "$@"; do >- [[ $w = "$word" ]] && return >- done >-} >- >-__filter_units_by_property () { >- local mode=$1 property=$2 value=$3 ; shift 3 >- local units=("$@") >- local props >- IFS=$'\n' read -rd '' -a props < \ >- <(__systemctl $mode show --property "$property" -- "${units[@]}") >- for ((i=0; $i < ${#units[*]}; i++)); do >- if [[ "${props[i]}" = "$property=$value" ]]; then >- echo " ${units[i]}" >- fi >- done >-} >- >-__get_all_units () { __systemctl $1 list-units --all \ >- | { while read -r a b; do echo " $a"; done; }; } >-__get_active_units () { __systemctl $1 list-units \ >- | { while read -r a b; do echo " $a"; done; }; } >-__get_startable_units () { __systemctl $1 list-units --all -t service,timer,socket,mount,automount,path,snapshot,swap \ >- | { while read -r a b c d; do [[ $c == "inactive" || $c == "failed" ]] && echo " $a"; done; }; } >-__get_failed_units () { __systemctl $1 list-units \ >- | { while read -r a b c d; do [[ $c == "failed" ]] && echo " $a"; done; }; } >-__get_enabled_units () { __systemctl $1 list-unit-files \ >- | { while read -r a b c ; do [[ $b == "enabled" ]] && echo " $a"; done; }; } >-__get_disabled_units () { __systemctl $1 list-unit-files \ >- | { while read -r a b c ; do [[ $b == "disabled" ]] && echo " $a"; done; }; } >-__get_masked_units () { __systemctl $1 list-unit-files \ >- | { while read -r a b c ; do [[ $b == "masked" ]] && echo " $a"; done; }; } >- >-_systemctl () { >- local cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]} >- local i verb comps mode >- >- local -A OPTS=( >- [STANDALONE]='--all -a --reverse --after --before --defaults --fail --ignore-dependencies --failed --force -f --full -l --global >- --help -h --no-ask-password --no-block --no-legend --no-pager --no-reload --no-wall >- --quiet -q --privileged -P --system --user --version --runtime --recursive -r' >- [ARG]='--host -H --kill-who --property -p --signal -s --type -t --state --root' >- ) >- >- if __contains_word "--user" ${COMP_WORDS[*]}; then >- mode=--user >- else >- mode=--system >- fi >- >- if __contains_word "$prev" ${OPTS[ARG]}; then >- case $prev in >- --signal|-s) >- comps=$(compgen -A signal) >- ;; >- --type|-t) >- comps='automount device mount path service snapshot socket swap target timer' >- ;; >- --state) >- comps='loaded not-found stub >- active inactive >- dead elapsed exited listening mounted plugged running waiting' >- ;; >- --kill-who) >- comps='all control main' >- ;; >- --root) >- comps=$(compgen -A directory -- "$cur" ) >- compopt -o filenames >- ;; >- --host|-H) >- comps=$(compgen -A hostname) >- ;; >- --property|-p) >- comps=$(__systemd_properties $mode) >- ;; >- esac >- COMPREPLY=( $(compgen -W '$comps' -- "$cur") ) >- return 0 >- fi >- >- if [[ "$cur" = -* ]]; then >- COMPREPLY=( $(compgen -W '${OPTS[*]}' -- "$cur") ) >- return 0 >- fi >- >- local -A VERBS=( >- [ALL_UNITS]='is-active is-failed is-enabled status show cat mask preset help list-dependencies' >- [ENABLED_UNITS]='disable' >- [DISABLED_UNITS]='enable' >- [REENABLABLE_UNITS]='reenable' >- [FAILED_UNITS]='reset-failed' >- [STARTABLE_UNITS]='start' >- [STOPPABLE_UNITS]='stop condstop kill try-restart condrestart' >- [ISOLATABLE_UNITS]='isolate' >- [RELOADABLE_UNITS]='reload condreload reload-or-try-restart force-reload' >- [RESTARTABLE_UNITS]='restart reload-or-restart' >- [MASKED_UNITS]='unmask' >- [JOBS]='cancel' >- [SNAPSHOTS]='delete' >- [ENVS]='set-environment unset-environment' >- [STANDALONE]='daemon-reexec daemon-reload default >- emergency exit halt hibernate hybrid-sleep kexec list-jobs >- list-sockets list-timers list-units list-unit-files poweroff >- reboot rescue show-environment suspend get-default' >- [NAME]='snapshot' >- [FILE]='link' >- [TARGETS]='set-default' >- ) >- >- for ((i=0; i < COMP_CWORD; i++)); do >- if __contains_word "${COMP_WORDS[i]}" ${VERBS[*]} && >- ! __contains_word "${COMP_WORDS[i-1]}" ${OPTS[ARG]}; then >- verb=${COMP_WORDS[i]} >- break >- fi >- done >- >- if [[ -z $verb ]]; then >- comps="${VERBS[*]}" >- >- elif __contains_word "$verb" ${VERBS[ALL_UNITS]}; then >- comps=$( __get_all_units $mode ) >- >- elif __contains_word "$verb" ${VERBS[ENABLED_UNITS]}; then >- comps=$( __get_enabled_units $mode ) >- >- elif __contains_word "$verb" ${VERBS[DISABLED_UNITS]}; then >- comps=$( __get_disabled_units $mode ) >- >- elif __contains_word "$verb" ${VERBS[REENABLABLE_UNITS]}; then >- comps=$( __get_disabled_units $mode; >- __get_enabled_units $mode ) >- >- elif __contains_word "$verb" ${VERBS[STARTABLE_UNITS]}; then >- comps=$( __filter_units_by_property $mode CanStart yes \ >- $( __get_startable_units $mode)) >- >- elif __contains_word "$verb" ${VERBS[RESTARTABLE_UNITS]}; then >- comps=$( __filter_units_by_property $mode CanStart yes \ >- $( __get_all_units $mode \ >- | while read -r line; do \ >- [[ "$line" =~ \.(device|snapshot|socket|timer)$ ]] || echo " $line"; \ >- done )) >- >- elif __contains_word "$verb" ${VERBS[STOPPABLE_UNITS]}; then >- comps=$( __filter_units_by_property $mode CanStop yes \ >- $( __get_active_units $mode ) ) >- >- elif __contains_word "$verb" ${VERBS[RELOADABLE_UNITS]}; then >- comps=$( __filter_units_by_property $mode CanReload yes \ >- $( __get_active_units $mode ) ) >- >- elif __contains_word "$verb" ${VERBS[ISOLATABLE_UNITS]}; then >- comps=$( __filter_units_by_property $mode AllowIsolate yes \ >- $( __get_all_units $mode ) ) >- >- elif __contains_word "$verb" ${VERBS[FAILED_UNITS]}; then >- comps=$( __get_failed_units $mode ) >- >- elif __contains_word "$verb" ${VERBS[MASKED_UNITS]}; then >- comps=$( __get_masked_units $mode ) >- >- elif __contains_word "$verb" ${VERBS[STANDALONE]} ${VERBS[NAME]}; then >- comps='' >- >- elif __contains_word "$verb" ${VERBS[JOBS]}; then >- comps=$( __systemctl $mode list-jobs | { while read -r a b; do echo " $a"; done; } ) >- >- elif __contains_word "$verb" ${VERBS[SNAPSHOTS]}; then >- comps=$( __systemctl $mode list-units --type snapshot --full --all \ >- | { while read -r a b; do echo " $a"; done; } ) >- >- elif __contains_word "$verb" ${VERBS[ENVS]}; then >- comps=$( __systemctl $mode show-environment \ >- | while read -r line; do echo " ${line%%=*}=";done ) >- compopt -o nospace >- >- elif __contains_word "$verb" ${VERBS[FILE]}; then >- comps=$( compgen -A file -- "$cur" ) >- compopt -o filenames >- elif __contains_word "$verb" ${VERBS[TARGETS]}; then >- comps=$( __systemctl $mode list-unit-files --type target --full --all \ >- | { while read -r a b; do echo " $a"; done; } ) >- fi >- >- COMPREPLY=( $(compgen -W '$comps' -- "$cur") ) >- return 0 >-} >- >-complete -F _systemctl systemctl >diff --git a/shell-completion/bash/systemctl.in b/shell-completion/bash/systemctl.in >new file mode 100644 >index 0000000..4beec4e >--- /dev/null >+++ b/shell-completion/bash/systemctl.in >@@ -0,0 +1,226 @@ >+# systemctl(1) completion -*- shell-script -*- >+# >+# This file is part of systemd. >+# >+# Copyright 2010 Ran Benita >+# >+# 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 >+# 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/>. >+ >+__systemctl() { >+ local mode=$1; shift 1 >+ systemctl $mode --full --no-legend "$@" >+} >+ >+__systemd_properties() { >+ local mode=$1 >+ { __systemctl $mode show --all; >+ @rootlibexecdir@/systemd --dump-configuration-items; } | >+ while IFS='=' read -r key value; do >+ [[ $value ]] && echo "$key" >+ done >+} >+ >+__contains_word () { >+ local w word=$1; shift >+ for w in "$@"; do >+ [[ $w = "$word" ]] && return >+ done >+} >+ >+__filter_units_by_property () { >+ local mode=$1 property=$2 value=$3 ; shift 3 >+ local units=("$@") >+ local props >+ IFS=$'\n' read -rd '' -a props < \ >+ <(__systemctl $mode show --property "$property" -- "${units[@]}") >+ for ((i=0; $i < ${#units[*]}; i++)); do >+ if [[ "${props[i]}" = "$property=$value" ]]; then >+ echo " ${units[i]}" >+ fi >+ done >+} >+ >+__get_all_units () { __systemctl $1 list-units --all \ >+ | { while read -r a b; do echo " $a"; done; }; } >+__get_active_units () { __systemctl $1 list-units \ >+ | { while read -r a b; do echo " $a"; done; }; } >+__get_startable_units () { __systemctl $1 list-units --all -t service,timer,socket,mount,automount,path,snapshot,swap \ >+ | { while read -r a b c d; do [[ $c == "inactive" || $c == "failed" ]] && echo " $a"; done; }; } >+__get_failed_units () { __systemctl $1 list-units \ >+ | { while read -r a b c d; do [[ $c == "failed" ]] && echo " $a"; done; }; } >+__get_enabled_units () { __systemctl $1 list-unit-files \ >+ | { while read -r a b c ; do [[ $b == "enabled" ]] && echo " $a"; done; }; } >+__get_disabled_units () { __systemctl $1 list-unit-files \ >+ | { while read -r a b c ; do [[ $b == "disabled" ]] && echo " $a"; done; }; } >+__get_masked_units () { __systemctl $1 list-unit-files \ >+ | { while read -r a b c ; do [[ $b == "masked" ]] && echo " $a"; done; }; } >+ >+_systemctl () { >+ local cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]} >+ local i verb comps mode >+ >+ local -A OPTS=( >+ [STANDALONE]='--all -a --reverse --after --before --defaults --fail --ignore-dependencies --failed --force -f --full -l --global >+ --help -h --no-ask-password --no-block --no-legend --no-pager --no-reload --no-wall >+ --quiet -q --privileged -P --system --user --version --runtime --recursive -r' >+ [ARG]='--host -H --kill-who --property -p --signal -s --type -t --state --root' >+ ) >+ >+ if __contains_word "--user" ${COMP_WORDS[*]}; then >+ mode=--user >+ else >+ mode=--system >+ fi >+ >+ if __contains_word "$prev" ${OPTS[ARG]}; then >+ case $prev in >+ --signal|-s) >+ comps=$(compgen -A signal) >+ ;; >+ --type|-t) >+ comps='automount device mount path service snapshot socket swap target timer' >+ ;; >+ --state) >+ comps='loaded not-found stub >+ active inactive >+ dead elapsed exited listening mounted plugged running waiting' >+ ;; >+ --kill-who) >+ comps='all control main' >+ ;; >+ --root) >+ comps=$(compgen -A directory -- "$cur" ) >+ compopt -o filenames >+ ;; >+ --host|-H) >+ comps=$(compgen -A hostname) >+ ;; >+ --property|-p) >+ comps=$(__systemd_properties $mode) >+ ;; >+ esac >+ COMPREPLY=( $(compgen -W '$comps' -- "$cur") ) >+ return 0 >+ fi >+ >+ if [[ "$cur" = -* ]]; then >+ COMPREPLY=( $(compgen -W '${OPTS[*]}' -- "$cur") ) >+ return 0 >+ fi >+ >+ local -A VERBS=( >+ [ALL_UNITS]='is-active is-failed is-enabled status show cat mask preset help list-dependencies' >+ [ENABLED_UNITS]='disable' >+ [DISABLED_UNITS]='enable' >+ [REENABLABLE_UNITS]='reenable' >+ [FAILED_UNITS]='reset-failed' >+ [STARTABLE_UNITS]='start' >+ [STOPPABLE_UNITS]='stop condstop kill try-restart condrestart' >+ [ISOLATABLE_UNITS]='isolate' >+ [RELOADABLE_UNITS]='reload condreload reload-or-try-restart force-reload' >+ [RESTARTABLE_UNITS]='restart reload-or-restart' >+ [MASKED_UNITS]='unmask' >+ [JOBS]='cancel' >+ [SNAPSHOTS]='delete' >+ [ENVS]='set-environment unset-environment' >+ [STANDALONE]='daemon-reexec daemon-reload default >+ emergency exit halt hibernate hybrid-sleep kexec list-jobs >+ list-sockets list-timers list-units list-unit-files poweroff >+ reboot rescue show-environment suspend get-default' >+ [NAME]='snapshot' >+ [FILE]='link' >+ [TARGETS]='set-default' >+ ) >+ >+ for ((i=0; i < COMP_CWORD; i++)); do >+ if __contains_word "${COMP_WORDS[i]}" ${VERBS[*]} && >+ ! __contains_word "${COMP_WORDS[i-1]}" ${OPTS[ARG]}; then >+ verb=${COMP_WORDS[i]} >+ break >+ fi >+ done >+ >+ if [[ -z $verb ]]; then >+ comps="${VERBS[*]}" >+ >+ elif __contains_word "$verb" ${VERBS[ALL_UNITS]}; then >+ comps=$( __get_all_units $mode ) >+ >+ elif __contains_word "$verb" ${VERBS[ENABLED_UNITS]}; then >+ comps=$( __get_enabled_units $mode ) >+ >+ elif __contains_word "$verb" ${VERBS[DISABLED_UNITS]}; then >+ comps=$( __get_disabled_units $mode ) >+ >+ elif __contains_word "$verb" ${VERBS[REENABLABLE_UNITS]}; then >+ comps=$( __get_disabled_units $mode; >+ __get_enabled_units $mode ) >+ >+ elif __contains_word "$verb" ${VERBS[STARTABLE_UNITS]}; then >+ comps=$( __filter_units_by_property $mode CanStart yes \ >+ $( __get_startable_units $mode)) >+ >+ elif __contains_word "$verb" ${VERBS[RESTARTABLE_UNITS]}; then >+ comps=$( __filter_units_by_property $mode CanStart yes \ >+ $( __get_all_units $mode \ >+ | while read -r line; do \ >+ [[ "$line" =~ \.(device|snapshot|socket|timer)$ ]] || echo " $line"; \ >+ done )) >+ >+ elif __contains_word "$verb" ${VERBS[STOPPABLE_UNITS]}; then >+ comps=$( __filter_units_by_property $mode CanStop yes \ >+ $( __get_active_units $mode ) ) >+ >+ elif __contains_word "$verb" ${VERBS[RELOADABLE_UNITS]}; then >+ comps=$( __filter_units_by_property $mode CanReload yes \ >+ $( __get_active_units $mode ) ) >+ >+ elif __contains_word "$verb" ${VERBS[ISOLATABLE_UNITS]}; then >+ comps=$( __filter_units_by_property $mode AllowIsolate yes \ >+ $( __get_all_units $mode ) ) >+ >+ elif __contains_word "$verb" ${VERBS[FAILED_UNITS]}; then >+ comps=$( __get_failed_units $mode ) >+ >+ elif __contains_word "$verb" ${VERBS[MASKED_UNITS]}; then >+ comps=$( __get_masked_units $mode ) >+ >+ elif __contains_word "$verb" ${VERBS[STANDALONE]} ${VERBS[NAME]}; then >+ comps='' >+ >+ elif __contains_word "$verb" ${VERBS[JOBS]}; then >+ comps=$( __systemctl $mode list-jobs | { while read -r a b; do echo " $a"; done; } ) >+ >+ elif __contains_word "$verb" ${VERBS[SNAPSHOTS]}; then >+ comps=$( __systemctl $mode list-units --type snapshot --full --all \ >+ | { while read -r a b; do echo " $a"; done; } ) >+ >+ elif __contains_word "$verb" ${VERBS[ENVS]}; then >+ comps=$( __systemctl $mode show-environment \ >+ | while read -r line; do echo " ${line%%=*}=";done ) >+ compopt -o nospace >+ >+ elif __contains_word "$verb" ${VERBS[FILE]}; then >+ comps=$( compgen -A file -- "$cur" ) >+ compopt -o filenames >+ elif __contains_word "$verb" ${VERBS[TARGETS]}; then >+ comps=$( __systemctl $mode list-unit-files --type target --full --all \ >+ | { while read -r a b; do echo " $a"; done; } ) >+ fi >+ >+ COMPREPLY=( $(compgen -W '$comps' -- "$cur") ) >+ return 0 >+} >+ >+complete -F _systemctl systemctl >diff --git a/shell-completion/zsh/.gitignore b/shell-completion/zsh/.gitignore >new file mode 100644 >index 0000000..75f13ad >--- /dev/null >+++ b/shell-completion/zsh/.gitignore >@@ -0,0 +1 @@ >+/_systemctl >diff --git a/shell-completion/zsh/_hostnamectl b/shell-completion/zsh/_hostnamectl >index 7effa04..be86876 100644 >--- a/shell-completion/zsh/_hostnamectl >+++ b/shell-completion/zsh/_hostnamectl >@@ -1,5 +1,30 @@ > #compdef hostnamectl > >+_hostnamectl_set-hostname() { >+ if (( CURRENT <= 3 )); then >+ _message "new hostname" >+ else >+ _message "no more options" >+ fi >+} >+ >+_hostnamectl_set-icon-name() { >+ if (( CURRENT <= 3 )); then >+ _message "new icon name" >+ else >+ _message "no more options" >+ fi >+} >+ >+_hostnamectl_set-chassis() { >+ if (( CURRENT <= 3 )); then >+ _chassis=( desktop laptop server tablet handset watch vm container ) >+ _describe chassis _chassis >+ else >+ _message "no more options" >+ fi >+} >+ > _hostnamectl_command() { > local -a _hostnamectl_cmds > _hostnamectl_cmds=( >@@ -14,8 +39,11 @@ _hostnamectl_command() { > local curcontext="$curcontext" > cmd="${${_hostnamectl_cmds[(r)$words[1]:*]%%:*}}" > if (( $#cmd )); then >- [[ $cmd == status ]] && msg="no options" || msg="options for $cmd" >- _message "$msg" >+ if [[ $cmd == status ]]; then >+ _message "no options" >+ else >+ _hostnamectl_$cmd >+ fi > else > _message "unknown hostnamectl command: $words[1]" > fi >diff --git a/shell-completion/zsh/_localectl b/shell-completion/zsh/_localectl >index 87432da..d8af4d1 100644 >--- a/shell-completion/zsh/_localectl >+++ b/shell-completion/zsh/_localectl >@@ -22,8 +22,8 @@ _localectl_set-locale() { > > _localectl_set-keymap() { > local -a _keymaps >- _keymaps=( ${(f)"$(_call_program locales "$service" list-keymaps)"} ) > if (( CURRENT <= 3 )); then >+ _keymaps=( ${(f)"$(_call_program locales "$service" list-keymaps)"} ) > _describe keymaps _keymaps > else > _message "no more options" >@@ -77,7 +77,7 @@ _localectl_command() { > if (( $+functions[_localectl_$cmd] )); then > _localectl_$cmd > else >- _message "no more options" >+ _message "unknown localectl command: $words[1]" > fi > fi > } >diff --git a/shell-completion/zsh/_systemctl b/shell-completion/zsh/_systemctl >deleted file mode 100644 >index b6cf664..0000000 >--- a/shell-completion/zsh/_systemctl >+++ /dev/null >@@ -1,341 +0,0 @@ >-#compdef systemctl >- >-(( $+functions[_systemctl_command] )) || _systemctl_command() >-{ >- local -a _systemctl_cmds >- _systemctl_cmds=( >- "list-sockets:List sockets" >- "list-timers:List timers" >- "list-units:List units" >- "start:Start (activate) one or more units" >- "stop:Stop (deactivate) one or more units" >- "reload:Reload one or more units" >- "restart:Start or restart one or more units" >- "condrestart:Restart one or more units if active" >- "try-restart:Restart one or more units if active" >- "reload-or-restart:Reload one or more units if possible, otherwise start or restart" >- "force-reload:Reload one or more units if possible, otherwise restart if active" >- "hibernate:Hibernate the system" >- "hybrid-sleep:Hibernate and suspend the system" >- "reload-or-try-restart:Reload one or more units if possible, otherwise restart if active" >- "isolate:Start one unit and stop all others" >- "kill:Send signal to processes of a unit" >- "is-active:Check whether units are active" >- "is-failed:Check whether units are failed" >- "status:Show runtime status of one or more units" >- "show:Show properties of one or more units/jobs or the manager" >- "cat:Show the source unit files and drop-ins" >- "reset-failed:Reset failed state for all, one, or more units" >- "list-unit-files:List installed unit files" >- "enable:Enable one or more unit files" >- "disable:Disable one or more unit files" >- "reenable:Reenable one or more unit files" >- "preset:Enable/disable one or more unit files based on preset configuration" >- "help:Show documentation for specified units" >- "list-dependencies:Show unit dependency tree" >- "mask:Mask one or more units" >- "unmask:Unmask one or more units" >- "link:Link one or more units files into the search path" >- "is-enabled:Check whether unit files are enabled" >- "list-jobs:List jobs" >- "cancel:Cancel all, one, or more jobs" >- "snapshot:Create a snapshot" >- "delete:Remove one or more snapshots" >- "show-environment:Dump environment" >- "set-environment:Set one or more environment variables" >- "unset-environment:Unset one or more environment variables" >- "daemon-reload:Reload systemd manager configuration" >- "daemon-reexec:Reexecute systemd manager" >- "default:Enter system default mode" >- "rescue:Enter system rescue mode" >- "emergency:Enter system emergency mode" >- "halt:Shut down and halt the system" >- "suspend:Suspend the system" >- "poweroff:Shut down and power-off the system" >- "reboot:Shut down and reboot the system" >- "kexec:Shut down and reboot the system with kexec" >- "exit:Ask for user instance termination" >- ) >- >- if (( CURRENT == 1 )); then >- _describe -t commands 'systemctl command' _systemctl_cmds || compadd "$@" >- else >- local curcontext="$curcontext" >- >- cmd="${${_systemctl_cmds[(r)$words[1]:*]%%:*}}" >- # Deal with any aliases >- case $cmd in >- condrestart) cmd="try-restart";; >- force-reload) cmd="reload-or-try-restart";; >- esac >- >- if (( $#cmd )); then >- curcontext="${curcontext%:*:*}:systemctl-${cmd}:" >- >- local update_policy >- zstyle -s ":completion:${curcontext}:" cache-policy update_policy >- if [[ -z "$update_policy" ]]; then >- zstyle ":completion:${curcontext}:" cache-policy _systemctl_caching_policy >- fi >- >- _call_function ret _systemctl_$cmd || _message 'no more arguments' >- else >- _message "unknown systemctl command: $words[1]" >- fi >- return ret >- fi >-} >- >-__systemctl() >-{ >- local -a _modes >- _modes=("--user" "--system") >- systemctl ${words:*_modes} --full --no-legend --no-pager "$@" >-} >- >- >-# Fills the unit list >-_systemctl_all_units() >-{ >- if ( [[ ${+_sys_all_units} -eq 0 ]] || _cache_invalid SYS_ALL_UNITS ) && >- ! _retrieve_cache SYS_ALL_UNITS; >- then >- _sys_all_units=( $(__systemctl list-units --all | { while read a b; do echo " $a"; done; }) ) >- _store_cache SYS_ALL_UNITS _sys_all_units >- fi >-} >- >-# Fills the unit list including all file units >-_systemctl_really_all_units() >-{ >- local -a all_unit_files; >- local -a really_all_units; >- if ( [[ ${+_sys_really_all_units} -eq 0 ]] || _cache_invalid SYS_REALLY_ALL_UNITS ) && >- ! _retrieve_cache SYS_REALLY_ALL_UNITS; >- then >- all_unit_files=( $(__systemctl list-unit-files | { while read a b; do echo " $a"; done; }) ) >- _systemctl_all_units >- really_all_units=($_sys_all_units $all_unit_files) >- _sys_really_all_units=(${(u)really_all_units}) >- _store_cache SYS_REALLY_ALL_UNITS _sys_really_all_units >- fi >-} >- >-_filter_units_by_property() { >- local property=$1 value=$2 ; shift ; shift >- local -a units ; units=($*) >- local prop unit >- for ((i=1; $i <= ${#units[*]}; i++)); do >- # FIXME: "Failed to issue method call: Unknown unit" errors are ignored for >- # now (related to DBUS_ERROR_UNKNOWN_OBJECT). in the future, we need to >- # revert to calling 'systemctl show' once for all units, which is way >- # faster >- unit=${units[i]} >- prop=${(f)"$(_call_program units "$service show --no-pager --property="$property" ${unit} 2>/dev/null")"} >- if [[ "${prop}" = "$property=$value" ]]; then >- echo " ${unit}" >- fi >- done >-} >- >-_systemctl_active_units() {_sys_active_units=( $(__systemctl list-units | { while read a b; do echo " $a"; done; }) )} >-_systemctl_inactive_units(){_sys_inactive_units=($(__systemctl list-units --all | { while read a b c d; do [[ $c == "inactive" || $c == "failed" ]] && echo " $a"; done; }) )} >-_systemctl_failed_units() {_sys_failed_units=( $(__systemctl list-units --failed | { while read a b; do echo " $a"; done; }) )} >-_systemctl_enabled_units() {_sys_enabled_units=( $(__systemctl list-unit-files | { while read a b; do [[ $b == "enabled" ]] && echo " $a"; done; }) )} >-_systemctl_disabled_units(){_sys_disabled_units=($(__systemctl list-unit-files | { while read a b; do [[ $b == "disabled" ]] && echo " $a"; done; }) )} >-_systemctl_masked_units() {_sys_masked_units=( $(__systemctl list-unit-files | { while read a b; do [[ $b == "masked" ]] && echo " $a"; done; }) )} >- >-# Completion functions for ALL_UNITS >-for fun in is-active is-failed is-enabled status show cat mask preset help list-dependencies ; do >- (( $+functions[_systemctl_$fun] )) || _systemctl_$fun() >- { >- _systemctl_really_all_units >- compadd "$@" -a - _sys_really_all_units >- } >-done >- >-# Completion functions for ENABLED_UNITS >-for fun in disable reenable ; do >- (( $+functions[_systemctl_$fun] )) || _systemctl_$fun() >- { >- _systemctl_enabled_units >- _systemctl_disabled_units >- compadd "$@" -a - _sys_enabled_units _sys_disabled_units >- } >-done >- >-# Completion functions for DISABLED_UNITS >-(( $+functions[_systemctl_enable] )) || _systemctl_enable() >-{ >- _systemctl_disabled_units >- compadd "$@" -a - _sys_disabled_units >-} >- >-# Completion functions for FAILED_UNITS >-(( $+functions[_systemctl_reset-failed] )) || _systemctl_reset-failed() >-{ >- _systemctl_failed_units >- compadd "$@" -a - _sys_failed_units || _message "no failed unit found" >-} >- >-# Completion functions for STARTABLE_UNITS >-(( $+functions[_systemctl_start] )) || _systemctl_start() >-{ >- _systemctl_inactive_units >- compadd "$@" -a - _sys_inactive_units >-} >- >-# Completion functions for STOPPABLE_UNITS >-for fun in stop kill try-restart condrestart ; do >- (( $+functions[_systemctl_$fun] )) || _systemctl_$fun() >- { >- _systemctl_active_units >- compadd "$@" - $( _filter_units_by_property CanStop yes \ >- ${_sys_active_units[*]} ) >- } >-done >- >-# Completion functions for ISOLATABLE_UNITS >-(( $+functions[_systemctl_isolate] )) || _systemctl_isolate() >-{ >- _systemctl_all_units >- compadd "$@" - $( _filter_units_by_property AllowIsolate yes \ >- ${_sys_all_units[*]} ) >-} >- >-# Completion functions for RELOADABLE_UNITS >-for fun in reload reload-or-try-restart force-reload ; do >- (( $+functions[_systemctl_$fun] )) || _systemctl_$fun() >- { >- _systemctl_active_units >- compadd "$@" - $( _filter_units_by_property CanReload yes \ >- ${_sys_active_units[*]} ) >- } >-done >- >-# Completion functions for RESTARTABLE_UNITS >-for fun in restart reload-or-restart ; do >- (( $+functions[_systemctl_$fun] )) || _systemctl_$fun() >- { >- _systemctl_all_units >- compadd "$@" - $( _filter_units_by_property CanStart yes \ >- ${_sys_all_units[*]} | while read line; do \ >- [[ "$line" =~ \.device$ ]] || echo " $line"; \ >- done ) >- } >-done >- >-# Completion functions for MASKED_UNITS >-(( $+functions[_systemctl_unmask] )) || _systemctl_unmask() >-{ >- _systemctl_masked_units >- compadd "$@" -a - _sys_masked_units || _message "no masked unit found" >-} >- >-# Completion functions for JOBS >-(( $+functions[_systemctl_cancel] )) || _systemctl_cancel() >-{ >- compadd "$@" - $(__systemctl list-jobs \ >- | cut -d' ' -f1 2>/dev/null ) || _message "no job found" >-} >- >-# Completion functions for SNAPSHOTS >-(( $+functions[_systemctl_delete] )) || _systemctl_delete() >-{ >- compadd "$@" - $(__systemctl list-units --type snapshot --all \ >- | cut -d' ' -f1 2>/dev/null ) || _message "no snapshot found" >-} >- >-# Completion functions for ENVS >-for fun in set-environment unset-environment ; do >- (( $+functions[_systemctl_$fun] )) || _systemctl_$fun() >- { >- local fun=$0 ; fun=${fun##_systemctl_} >- local suf >- if [[ "${fun}" = "set-environment" ]]; then >- suf='-S=' >- fi >- >- compadd "$@" ${suf} - $(systemctl show-environment \ >- | while read line; do echo " ${line%%\=}";done ) >- } >-done >- >-(( $+functions[_systemctl_link] )) || _systemctl_link() { _files } >- >-# no systemctl completion for: >-# [STANDALONE]='daemon-reexec daemon-reload default >-# emergency exit halt kexec list-jobs list-units >-# list-unit-files poweroff reboot rescue show-environment' >-# [NAME]='snapshot' >- >-_systemctl_caching_policy() >-{ >- local _sysunits >- local -a oldcache >- >- # rebuild if cache is more than a day old >- oldcache=( "$1"(mh+1) ) >- (( $#oldcache )) && return 0 >- >- _sysunits=($(__systemctl --all | cut -d' ' -f1)) >- >- if (( $#_sysunits )); then >- for unit in $_sysunits; do >- [[ "$unit" -nt "$1" ]] && return 0 >- done >- fi >- >- return 1 >-} >- >-_unit_states() { >- local -a _states >- _states=(loaded failed active inactive not-found listening running waiting plugged mounted exited dead masked) >- _values -s , "${_states[@]}" >-} >- >-_unit_types() { >- local -a _types >- _types=(automount device mount path service snapshot socket swap target timer) >- _values -s , "${_types[@]}" >-} >- >-_arguments -s \ >- {-h,--help}'[Show help]' \ >- '--version[Show package version]' \ >- {-t+,--type=}'[List only units of a particular type]:unit type:_unit_types' \ >- '--state=[Display units in the specifyied state]:unit state:_unit_states' \ >- \*{-p+,--property=}'[Show only properties by specific name]:unit property' \ >- {-a,--all}'[Show all units/properties, including dead/empty ones]' \ >- '--reverse[Show reverse dependencies]' \ >- '--after[Show units ordered after]' \ >- '--before[Show units ordered before]' \ >- '--failed[Show only failed units]' \ >- {-l,--full}"[Don't ellipsize unit names on output]" \ >- '--fail[When queueing a new job, fail if conflicting jobs are pending]' \ >- '--show-types[When showing sockets, show socket type]' \ >- '--irreversible[Mark transactions as irreversible]' \ >- '--ignore-dependencies[When queueing a new job, ignore all its dependencies]' \ >- {-i,--ignore-inhibitors}'[When executing a job, ignore jobs dependencies]' \ >- {-q,--quiet}'[Suppress output]' \ >- '--no-block[Do not wait until operation finished]' \ >- '--no-legend[Do not print a legend, i.e. the column headers and the footer with hints]' \ >- '--no-pager[Do not pipe output into a pager]' \ >- '--system[Connect to system manager]' \ >- '--user[Connect to user service manager]' \ >- "--no-wall[Don't send wall message before halt/power-off/reboot]" \ >- '--global[Enable/disable unit files globally]' \ >- "--no-reload[When enabling/disabling unit files, don't reload daemon configuration]" \ >- '--no-ask-password[Do not ask for system passwords]' \ >- '--kill-who=[Who to send signal to]:killwho:(main control all)' \ >- {-s+,--signal=}'[Which signal to send]:signal:_signals' \ >- {-f,--force}'[When enabling unit files, override existing symlinks. When shutting down, execute action immediately]' \ >- '--root=[Enable unit files in the specified root directory]:directory:_directories' \ >- '--runtime[Enable unit files only temporarily until next reboot]' \ >- {-H+,--host=}'[Operate on remote host]:userathost:_sd_hosts_or_user_at_host' \ >- {-P,--privileged}'[Acquire privileges before execution]' \ >- {-n+,--lines=}'[Journal entries to show]:number of entries' \ >- {-o+,--output=}'[Change journal output mode]:modes:_sd_outputmodes' \ >- '--plain[When used with list-dependencies, print output as a list]' \ >- '*::systemctl command:_systemctl_command' >diff --git a/shell-completion/zsh/_systemctl.in b/shell-completion/zsh/_systemctl.in >new file mode 100644 >index 0000000..d9b8d1c >--- /dev/null >+++ b/shell-completion/zsh/_systemctl.in >@@ -0,0 +1,354 @@ >+#compdef systemctl >+ >+(( $+functions[_systemctl_command] )) || _systemctl_command() >+{ >+ local -a _systemctl_cmds >+ _systemctl_cmds=( >+ "list-sockets:List sockets" >+ "list-timers:List timers" >+ "list-units:List units" >+ "start:Start (activate) one or more units" >+ "stop:Stop (deactivate) one or more units" >+ "reload:Reload one or more units" >+ "restart:Start or restart one or more units" >+ "condrestart:Restart one or more units if active" >+ "try-restart:Restart one or more units if active" >+ "reload-or-restart:Reload one or more units if possible, otherwise start or restart" >+ "force-reload:Reload one or more units if possible, otherwise restart if active" >+ "hibernate:Hibernate the system" >+ "hybrid-sleep:Hibernate and suspend the system" >+ "reload-or-try-restart:Reload one or more units if possible, otherwise restart if active" >+ "isolate:Start one unit and stop all others" >+ "kill:Send signal to processes of a unit" >+ "is-active:Check whether units are active" >+ "is-failed:Check whether units are failed" >+ "status:Show runtime status of one or more units" >+ "show:Show properties of one or more units/jobs or the manager" >+ "cat:Show the source unit files and drop-ins" >+ "reset-failed:Reset failed state for all, one, or more units" >+ "list-unit-files:List installed unit files" >+ "enable:Enable one or more unit files" >+ "disable:Disable one or more unit files" >+ "reenable:Reenable one or more unit files" >+ "preset:Enable/disable one or more unit files based on preset configuration" >+ "help:Show documentation for specified units" >+ "list-dependencies:Show unit dependency tree" >+ "mask:Mask one or more units" >+ "unmask:Unmask one or more units" >+ "link:Link one or more units files into the search path" >+ "is-enabled:Check whether unit files are enabled" >+ "list-jobs:List jobs" >+ "cancel:Cancel all, one, or more jobs" >+ "snapshot:Create a snapshot" >+ "delete:Remove one or more snapshots" >+ "show-environment:Dump environment" >+ "set-environment:Set one or more environment variables" >+ "unset-environment:Unset one or more environment variables" >+ "daemon-reload:Reload systemd manager configuration" >+ "daemon-reexec:Reexecute systemd manager" >+ "default:Enter system default mode" >+ "rescue:Enter system rescue mode" >+ "emergency:Enter system emergency mode" >+ "halt:Shut down and halt the system" >+ "suspend:Suspend the system" >+ "poweroff:Shut down and power-off the system" >+ "reboot:Shut down and reboot the system" >+ "kexec:Shut down and reboot the system with kexec" >+ "exit:Ask for user instance termination" >+ ) >+ >+ if (( CURRENT == 1 )); then >+ _describe -t commands 'systemctl command' _systemctl_cmds || compadd "$@" >+ else >+ local curcontext="$curcontext" >+ >+ cmd="${${_systemctl_cmds[(r)$words[1]:*]%%:*}}" >+ # Deal with any aliases >+ case $cmd in >+ condrestart) cmd="try-restart";; >+ force-reload) cmd="reload-or-try-restart";; >+ esac >+ >+ if (( $#cmd )); then >+ curcontext="${curcontext%:*:*}:systemctl-${cmd}:" >+ >+ local update_policy >+ zstyle -s ":completion:${curcontext}:" cache-policy update_policy >+ if [[ -z "$update_policy" ]]; then >+ zstyle ":completion:${curcontext}:" cache-policy _systemctl_caching_policy >+ fi >+ >+ _call_function ret _systemctl_$cmd || _message 'no more arguments' >+ else >+ _message "unknown systemctl command: $words[1]" >+ fi >+ return ret >+ fi >+} >+ >+__systemctl() >+{ >+ local -a _modes >+ _modes=("--user" "--system") >+ systemctl ${words:*_modes} --full --no-legend --no-pager "$@" >+} >+ >+ >+# Fills the unit list >+_systemctl_all_units() >+{ >+ if ( [[ ${+_sys_all_units} -eq 0 ]] || _cache_invalid SYS_ALL_UNITS ) && >+ ! _retrieve_cache SYS_ALL_UNITS; >+ then >+ _sys_all_units=( $(__systemctl list-units --all | { while read a b; do echo " $a"; done; }) ) >+ _store_cache SYS_ALL_UNITS _sys_all_units >+ fi >+} >+ >+# Fills the unit list including all file units >+_systemctl_really_all_units() >+{ >+ local -a all_unit_files; >+ local -a really_all_units; >+ if ( [[ ${+_sys_really_all_units} -eq 0 ]] || _cache_invalid SYS_REALLY_ALL_UNITS ) && >+ ! _retrieve_cache SYS_REALLY_ALL_UNITS; >+ then >+ all_unit_files=( $(__systemctl list-unit-files | { while read a b; do echo " $a"; done; }) ) >+ _systemctl_all_units >+ really_all_units=($_sys_all_units $all_unit_files) >+ _sys_really_all_units=(${(u)really_all_units}) >+ _store_cache SYS_REALLY_ALL_UNITS _sys_really_all_units >+ fi >+} >+ >+_filter_units_by_property() { >+ local property=$1 value=$2 ; shift ; shift >+ local -a units ; units=($*) >+ local prop unit >+ for ((i=1; $i <= ${#units[*]}; i++)); do >+ # FIXME: "Failed to issue method call: Unknown unit" errors are ignored for >+ # now (related to DBUS_ERROR_UNKNOWN_OBJECT). in the future, we need to >+ # revert to calling 'systemctl show' once for all units, which is way >+ # faster >+ unit=${units[i]} >+ prop=${(f)"$(_call_program units "$service show --no-pager --property="$property" ${unit} 2>/dev/null")"} >+ if [[ "${prop}" = "$property=$value" ]]; then >+ echo " ${unit}" >+ fi >+ done >+} >+ >+_systemctl_active_units() {_sys_active_units=( $(__systemctl list-units | { while read a b; do echo " $a"; done; }) )} >+_systemctl_inactive_units(){_sys_inactive_units=($(__systemctl list-units --all | { while read a b c d; do [[ $c == "inactive" || $c == "failed" ]] && echo " $a"; done; }) )} >+_systemctl_failed_units() {_sys_failed_units=( $(__systemctl list-units --failed | { while read a b; do echo " $a"; done; }) )} >+_systemctl_enabled_units() {_sys_enabled_units=( $(__systemctl list-unit-files | { while read a b; do [[ $b == "enabled" ]] && echo " $a"; done; }) )} >+_systemctl_disabled_units(){_sys_disabled_units=($(__systemctl list-unit-files | { while read a b; do [[ $b == "disabled" ]] && echo " $a"; done; }) )} >+_systemctl_masked_units() {_sys_masked_units=( $(__systemctl list-unit-files | { while read a b; do [[ $b == "masked" ]] && echo " $a"; done; }) )} >+ >+# Completion functions for ALL_UNITS >+for fun in is-active is-failed is-enabled status show cat mask preset help list-dependencies ; do >+ (( $+functions[_systemctl_$fun] )) || _systemctl_$fun() >+ { >+ _systemctl_really_all_units >+ compadd "$@" -a - _sys_really_all_units >+ } >+done >+ >+# Completion functions for ENABLED_UNITS >+for fun in disable reenable ; do >+ (( $+functions[_systemctl_$fun] )) || _systemctl_$fun() >+ { >+ _systemctl_enabled_units >+ _systemctl_disabled_units >+ compadd "$@" -a - _sys_enabled_units _sys_disabled_units >+ } >+done >+ >+# Completion functions for DISABLED_UNITS >+(( $+functions[_systemctl_enable] )) || _systemctl_enable() >+{ >+ _systemctl_disabled_units >+ compadd "$@" -a - _sys_disabled_units >+} >+ >+# Completion functions for FAILED_UNITS >+(( $+functions[_systemctl_reset-failed] )) || _systemctl_reset-failed() >+{ >+ _systemctl_failed_units >+ compadd "$@" -a - _sys_failed_units || _message "no failed unit found" >+} >+ >+# Completion functions for STARTABLE_UNITS >+(( $+functions[_systemctl_start] )) || _systemctl_start() >+{ >+ _systemctl_inactive_units >+ compadd "$@" -a - _sys_inactive_units >+} >+ >+# Completion functions for STOPPABLE_UNITS >+for fun in stop kill try-restart condrestart ; do >+ (( $+functions[_systemctl_$fun] )) || _systemctl_$fun() >+ { >+ _systemctl_active_units >+ compadd "$@" - $( _filter_units_by_property CanStop yes \ >+ ${_sys_active_units[*]} ) >+ } >+done >+ >+# Completion functions for ISOLATABLE_UNITS >+(( $+functions[_systemctl_isolate] )) || _systemctl_isolate() >+{ >+ _systemctl_all_units >+ compadd "$@" - $( _filter_units_by_property AllowIsolate yes \ >+ ${_sys_all_units[*]} ) >+} >+ >+# Completion functions for RELOADABLE_UNITS >+for fun in reload reload-or-try-restart force-reload ; do >+ (( $+functions[_systemctl_$fun] )) || _systemctl_$fun() >+ { >+ _systemctl_active_units >+ compadd "$@" - $( _filter_units_by_property CanReload yes \ >+ ${_sys_active_units[*]} ) >+ } >+done >+ >+# Completion functions for RESTARTABLE_UNITS >+for fun in restart reload-or-restart ; do >+ (( $+functions[_systemctl_$fun] )) || _systemctl_$fun() >+ { >+ _systemctl_all_units >+ compadd "$@" - $( _filter_units_by_property CanStart yes \ >+ ${_sys_all_units[*]} | while read line; do \ >+ [[ "$line" =~ \.device$ ]] || echo " $line"; \ >+ done ) >+ } >+done >+ >+# Completion functions for MASKED_UNITS >+(( $+functions[_systemctl_unmask] )) || _systemctl_unmask() >+{ >+ _systemctl_masked_units >+ compadd "$@" -a - _sys_masked_units || _message "no masked unit found" >+} >+ >+# Completion functions for JOBS >+(( $+functions[_systemctl_cancel] )) || _systemctl_cancel() >+{ >+ compadd "$@" - $(__systemctl list-jobs \ >+ | cut -d' ' -f1 2>/dev/null ) || _message "no job found" >+} >+ >+# Completion functions for SNAPSHOTS >+(( $+functions[_systemctl_delete] )) || _systemctl_delete() >+{ >+ compadd "$@" - $(__systemctl list-units --type snapshot --all \ >+ | cut -d' ' -f1 2>/dev/null ) || _message "no snapshot found" >+} >+ >+# Completion functions for ENVS >+for fun in set-environment unset-environment ; do >+ (( $+functions[_systemctl_$fun] )) || _systemctl_$fun() >+ { >+ local fun=$0 ; fun=${fun##_systemctl_} >+ local suf >+ if [[ "${fun}" = "set-environment" ]]; then >+ suf='-S=' >+ fi >+ >+ compadd "$@" ${suf} - $(systemctl show-environment \ >+ | while read line; do echo " ${line%%\=}";done ) >+ } >+done >+ >+(( $+functions[_systemctl_link] )) || _systemctl_link() { _files } >+ >+# no systemctl completion for: >+# [STANDALONE]='daemon-reexec daemon-reload default >+# emergency exit halt kexec list-jobs list-units >+# list-unit-files poweroff reboot rescue show-environment' >+# [NAME]='snapshot' >+ >+_systemctl_caching_policy() >+{ >+ local _sysunits >+ local -a oldcache >+ >+ # rebuild if cache is more than a day old >+ oldcache=( "$1"(mh+1) ) >+ (( $#oldcache )) && return 0 >+ >+ _sysunits=($(__systemctl --all | cut -d' ' -f1)) >+ >+ if (( $#_sysunits )); then >+ for unit in $_sysunits; do >+ [[ "$unit" -nt "$1" ]] && return 0 >+ done >+ fi >+ >+ return 1 >+} >+ >+_unit_states() { >+ local -a _states >+ _states=(loaded failed active inactive not-found listening running waiting plugged mounted exited dead masked) >+ _values -s , "${_states[@]}" >+} >+ >+_unit_types() { >+ local -a _types >+ _types=(automount device mount path service snapshot socket swap target timer) >+ _values -s , "${_types[@]}" >+} >+ >+_unit_properties() { >+ if ( [[ ${+_sys_all_properties} -eq 0 ]] || _cache_invalid SYS_ALL_PROPERTIES ) && >+ ! _retrieve_cache SYS_ALL_PROPERTIES; >+ then >+ _sys_all_properties=( $( {__systemctl show --all; >+ @rootlibexecdir@/systemd --dump-configuration-items; } | { >+ while IFS='=' read -r a b; do [ -n "$b" ] && echo "$a"; done >+ }) ) >+ _store_cache SYS_ALL_PROPRTIES _sys_all_properties >+ fi >+ _values -s , "${_sys_all_properties[@]}" >+} >+ >+_arguments -s \ >+ {-h,--help}'[Show help]' \ >+ '--version[Show package version]' \ >+ {-t+,--type=}'[List only units of a particular type]:unit type:_unit_types' \ >+ '--state=[Display units in the specifyied state]:unit state:_unit_states' \ >+ {-p+,--property=}'[Show only properties by specific name]:unit property:_unit_properties' \ >+ {-a,--all}'[Show all units/properties, including dead/empty ones]' \ >+ '--reverse[Show reverse dependencies]' \ >+ '--after[Show units ordered after]' \ >+ '--before[Show units ordered before]' \ >+ '--failed[Show only failed units]' \ >+ {-l,--full}"[Don't ellipsize unit names on output]" \ >+ '--fail[When queueing a new job, fail if conflicting jobs are pending]' \ >+ '--show-types[When showing sockets, show socket type]' \ >+ '--irreversible[Mark transactions as irreversible]' \ >+ '--ignore-dependencies[When queueing a new job, ignore all its dependencies]' \ >+ {-i,--ignore-inhibitors}'[When executing a job, ignore jobs dependencies]' \ >+ {-q,--quiet}'[Suppress output]' \ >+ '--no-block[Do not wait until operation finished]' \ >+ '--no-legend[Do not print a legend, i.e. the column headers and the footer with hints]' \ >+ '--no-pager[Do not pipe output into a pager]' \ >+ '--system[Connect to system manager]' \ >+ '--user[Connect to user service manager]' \ >+ "--no-wall[Don't send wall message before halt/power-off/reboot]" \ >+ '--global[Enable/disable unit files globally]' \ >+ "--no-reload[When enabling/disabling unit files, don't reload daemon configuration]" \ >+ '--no-ask-password[Do not ask for system passwords]' \ >+ '--kill-who=[Who to send signal to]:killwho:(main control all)' \ >+ {-s+,--signal=}'[Which signal to send]:signal:_signals' \ >+ {-f,--force}'[When enabling unit files, override existing symlinks. When shutting down, execute action immediately]' \ >+ '--root=[Enable unit files in the specified root directory]:directory:_directories' \ >+ '--runtime[Enable unit files only temporarily until next reboot]' \ >+ {-H+,--host=}'[Operate on remote host]:userathost:_sd_hosts_or_user_at_host' \ >+ {-P,--privileged}'[Acquire privileges before execution]' \ >+ {-n+,--lines=}'[Journal entries to show]:number of entries' \ >+ {-o+,--output=}'[Change journal output mode]:modes:_sd_outputmodes' \ >+ '--plain[When used with list-dependencies, print output as a list]' \ >+ '*::systemctl command:_systemctl_command' >diff --git a/src/core/main.c b/src/core/main.c >index 38835fc..a732c69 100644 >--- a/src/core/main.c >+++ b/src/core/main.c >@@ -1543,7 +1543,15 @@ int main(int argc, char *argv[]) { > if (in_initrd()) > log_info("Running in initial RAM disk."); > >- empty_etc = dir_is_empty("/etc") > 0; >+ /* Let's check whether /etc is already populated. We >+ * don't actually really check for that, but use >+ * /etc/machine-id as flag file. This allows container >+ * managers and installers to provision a couple of >+ * files already. If the container manager wants to >+ * provision the machine ID itself it should pass >+ * $container_uuid to PID 1.*/ >+ >+ empty_etc = access("/etc/machine-id", F_OK) < 0; > if (empty_etc) > log_info("Running with unpopulated /etc."); > } else { >diff --git a/src/core/manager.c b/src/core/manager.c >index 0cb2044..9b754d8 100644 >--- a/src/core/manager.c >+++ b/src/core/manager.c >@@ -554,7 +554,7 @@ static int manager_setup_notify(Manager *m) { > strncpy(sa.un.sun_path, m->notify_socket, sizeof(sa.un.sun_path)-1); > r = bind(fd, &sa.sa, offsetof(struct sockaddr_un, sun_path) + strlen(sa.un.sun_path)); > if (r < 0) { >- log_error("bind() failed: %m"); >+ log_error("bind(@%s) failed: %m", sa.un.sun_path+1); > return -errno; > } > >@@ -2539,7 +2539,8 @@ void manager_check_finished(Manager *m) { > } > > SET_FOREACH(u, m->startup_units, i) >- cgroup_context_apply(unit_get_cgroup_context(u), unit_get_cgroup_mask(u), u->cgroup_path, manager_state(m)); >+ if (u->cgroup_path) >+ cgroup_context_apply(unit_get_cgroup_context(u), unit_get_cgroup_mask(u), u->cgroup_path, manager_state(m)); > > bus_manager_send_finished(m, firmware_usec, loader_usec, kernel_usec, initrd_usec, userspace_usec, total_usec); > >diff --git a/src/core/path.c b/src/core/path.c >index 20e454d..f54c77f 100644 >--- a/src/core/path.c >+++ b/src/core/path.c >@@ -99,7 +99,8 @@ int path_spec_watch(PathSpec *s, sd_event_io_handler_t handler) { > break; > } > >- log_warning("Failed to add watch on %s: %m", s->path); >+ log_warning("Failed to add watch on %s: %s", s->path, >+ errno == ENOSPC ? "too many watches" : strerror(-r)); > r = -errno; > if (cut) > *cut = tmp; >diff --git a/src/core/service.c b/src/core/service.c >index 0b19767..73a0e84 100644 >--- a/src/core/service.c >+++ b/src/core/service.c >@@ -1699,6 +1699,9 @@ static int service_start(Unit *u) { > s->main_pid_alien = false; > s->forbid_restart = false; > >+ free(s->status_text); >+ s->status_text = NULL; >+ > service_enter_start_pre(s); > return 0; > } >@@ -2547,11 +2550,15 @@ static int service_dispatch_timer(sd_event_source *source, usec_t usec, void *us > > static int service_dispatch_watchdog(sd_event_source *source, usec_t usec, void *userdata) { > Service *s = SERVICE(userdata); >+ char t[FORMAT_TIMESPAN_MAX]; > > assert(s); > assert(source == s->watchdog_event_source); > >- log_error_unit(UNIT(s)->id, "%s watchdog timeout!", UNIT(s)->id); >+ log_error_unit(UNIT(s)->id, >+ "%s watchdog timeout (limit %s)!", >+ UNIT(s)->id, >+ format_timespan(t, sizeof(t), s->watchdog_usec, 1)); > service_enter_signal(s, SERVICE_STOP_SIGTERM, SERVICE_FAILURE_WATCHDOG); > > return 0; >diff --git a/src/escape/Makefile b/src/escape/Makefile >new file mode 120000 >index 0000000..d0b0e8e >--- /dev/null >+++ b/src/escape/Makefile >@@ -0,0 +1 @@ >+../Makefile >\ No newline at end of file >diff --git a/src/escape/escape.c b/src/escape/escape.c >new file mode 100644 >index 0000000..ba2fb47 >--- /dev/null >+++ b/src/escape/escape.c >@@ -0,0 +1,239 @@ >+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ >+ >+/*** >+ This file is part of systemd. >+ >+ Copyright 2014 Michael Biebl >+ >+ 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 <stdio.h> >+#include <stdlib.h> >+#include <getopt.h> >+ >+#include "log.h" >+#include "unit-name.h" >+#include "build.h" >+#include "strv.h" >+ >+static enum { >+ ACTION_ESCAPE, >+ ACTION_UNESCAPE, >+ ACTION_MANGLE >+} arg_action = ACTION_ESCAPE; >+static const char *arg_suffix = NULL; >+static const char *arg_template = NULL; >+static bool arg_path = false; >+ >+static int help(void) { >+ >+ printf("%s [OPTIONS...] [NAME...]\n\n" >+ "Show system and user paths.\n\n" >+ " -h --help Show this help\n" >+ " --version Show package version\n" >+ " --suffix=SUFFIX Unit suffix to append to escaped strings\n" >+ " --template=TEMPLATE Insert strings as instance into template\n" >+ " -u --unescape Unescape strings\n" >+ " -m --mangle Mangle strings\n" >+ " -p --path When escaping/unescaping assume the string is a path\n", >+ program_invocation_short_name); >+ >+ return 0; >+} >+ >+static int parse_argv(int argc, char *argv[]) { >+ >+ enum { >+ ARG_VERSION = 0x100, >+ ARG_SUFFIX, >+ ARG_TEMPLATE >+ }; >+ >+ static const struct option options[] = { >+ { "help", no_argument, NULL, 'h' }, >+ { "version", no_argument, NULL, ARG_VERSION }, >+ { "suffix", required_argument, NULL, ARG_SUFFIX }, >+ { "template", required_argument, NULL, ARG_TEMPLATE }, >+ { "unescape", no_argument, NULL, 'u' }, >+ { "mangle", no_argument, NULL, 'm' }, >+ { "path", no_argument, NULL, 'p' }, >+ {} >+ }; >+ >+ int c; >+ >+ assert(argc >= 0); >+ assert(argv); >+ >+ while ((c = getopt_long(argc, argv, "hump", options, NULL)) >= 0) { >+ >+ switch (c) { >+ >+ case 'h': >+ return help(); >+ >+ case ARG_VERSION: >+ puts(PACKAGE_STRING); >+ puts(SYSTEMD_FEATURES); >+ return 0; >+ >+ case ARG_SUFFIX: >+ >+ if (unit_type_from_string(optarg) < 0) { >+ log_error("Invalid unit suffix type %s.", optarg); >+ return -EINVAL; >+ } >+ >+ arg_suffix = optarg; >+ break; >+ >+ case ARG_TEMPLATE: >+ >+ if (!unit_name_is_valid(optarg, true) || !unit_name_is_template(optarg)) { >+ log_error("Template name %s is not valid.", optarg); >+ return -EINVAL; >+ } >+ >+ arg_template = optarg; >+ break; >+ >+ case 'u': >+ arg_action = ACTION_UNESCAPE; >+ break; >+ >+ case 'm': >+ arg_action = ACTION_MANGLE; >+ break; >+ >+ case 'p': >+ arg_path = true; >+ break; >+ >+ case '?': >+ return -EINVAL; >+ >+ default: >+ assert_not_reached("Unhandled option"); >+ } >+ } >+ >+ if (optind >= argc) { >+ log_error("Not enough arguments."); >+ return -EINVAL; >+ } >+ >+ if (arg_template && arg_suffix) { >+ log_error("--suffix= and --template= may not be combined."); >+ return -EINVAL; >+ } >+ >+ if ((arg_template || arg_suffix) && arg_action != ACTION_ESCAPE) { >+ log_error("--suffix= and --template= are not compatible with --unescape or --mangle."); >+ return -EINVAL; >+ } >+ >+ if (arg_path && !IN_SET(arg_action, ACTION_ESCAPE, ACTION_UNESCAPE)) { >+ log_error("--path may not be combined with --mangle."); >+ return -EINVAL; >+ } >+ >+ return 1; >+} >+ >+int main(int argc, char *argv[]) { >+ char **i; >+ int r; >+ >+ log_parse_environment(); >+ log_open(); >+ >+ r = parse_argv(argc, argv); >+ if (r <= 0) >+ goto finish; >+ >+ STRV_FOREACH(i, argv + optind) { >+ _cleanup_free_ char *e = NULL; >+ >+ switch (arg_action) { >+ >+ case ACTION_ESCAPE: >+ if (arg_path) >+ e = unit_name_path_escape(*i); >+ else >+ e = unit_name_escape(*i); >+ >+ if (!e) { >+ r = log_oom(); >+ goto finish; >+ } >+ >+ if (arg_template) { >+ char *x; >+ >+ x = unit_name_replace_instance(arg_template, e); >+ if (!x) { >+ r = log_oom(); >+ goto finish; >+ } >+ >+ free(e); >+ e = x; >+ } else if (arg_suffix) { >+ char *x; >+ >+ x = strjoin(e, ".", arg_suffix, NULL); >+ if (!x) { >+ r = log_oom(); >+ goto finish; >+ } >+ >+ free(e); >+ e = x; >+ } >+ >+ break; >+ >+ case ACTION_UNESCAPE: >+ if (arg_path) >+ e = unit_name_path_unescape(*i); >+ else >+ e = unit_name_unescape(*i); >+ >+ if (!e) { >+ r = log_oom(); >+ goto finish; >+ } >+ break; >+ >+ case ACTION_MANGLE: >+ e = unit_name_mangle(*i, MANGLE_NOGLOB); >+ if (!e) { >+ r = log_oom(); >+ goto finish; >+ } >+ break; >+ } >+ >+ if (i != argv+optind) >+ fputc(' ', stdout); >+ >+ fputs(e, stdout); >+ } >+ >+ fputc('\n', stdout); >+ >+finish: >+ return r <= 0 ? EXIT_FAILURE : EXIT_SUCCESS; >+} >diff --git a/src/hostname/hostnamed.c b/src/hostname/hostnamed.c >index 14629dd..eaae113 100644 >--- a/src/hostname/hostnamed.c >+++ b/src/hostname/hostnamed.c >@@ -144,7 +144,8 @@ static bool valid_chassis(const char *chassis) { > "laptop\0" > "server\0" > "tablet\0" >- "handset\0", >+ "handset\0" >+ "watch\0", > chassis); > } > >@@ -550,8 +551,7 @@ static int set_machine_info(Context *c, sd_bus *bus, sd_bus_message *m, int prop > > if (prop == PROP_ICON_NAME && !filename_is_safe(name)) > return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid icon name '%s'", name); >- if (prop == PROP_PRETTY_HOSTNAME && >- (string_has_cc(name) || chars_intersect(name, "\t"))) >+ if (prop == PROP_PRETTY_HOSTNAME && string_has_cc(name, NULL)) > return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid pretty host name '%s'", name); > if (prop == PROP_CHASSIS && !valid_chassis(name)) > return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid chassis '%s'", name); >diff --git a/src/journal/compress.c b/src/journal/compress.c >index 1fc62ea..9c0b74c 100644 >--- a/src/journal/compress.c >+++ b/src/journal/compress.c >@@ -30,6 +30,13 @@ > #include "util.h" > > bool compress_blob(const void *src, uint64_t src_size, void *dst, uint64_t *dst_size) { >+ static const lzma_options_lzma opt = { >+ 1u << 20u, NULL, 0, LZMA_LC_DEFAULT, LZMA_LP_DEFAULT, >+ LZMA_PB_DEFAULT, LZMA_MODE_FAST, 128, LZMA_MF_HC3, 4}; >+ static const lzma_filter filters[2] = { >+ {LZMA_FILTER_LZMA2, (lzma_options_lzma*) &opt}, >+ {LZMA_VLI_UNKNOWN, NULL} >+ }; > lzma_ret ret; > size_t out_pos = 0; > >@@ -41,8 +48,11 @@ bool compress_blob(const void *src, uint64_t src_size, void *dst, uint64_t *dst_ > /* Returns false if we couldn't compress the data or the > * compressed result is longer than the original */ > >- ret = lzma_easy_buffer_encode(LZMA_PRESET_DEFAULT, LZMA_CHECK_NONE, NULL, >- src, src_size, dst, &out_pos, src_size); >+ if (src_size < 80) >+ return -ENOBUFS; >+ >+ ret = lzma_stream_buffer_encode((lzma_filter*) filters, LZMA_CHECK_NONE, NULL, >+ src, src_size, dst, &out_pos, src_size - 1); > if (ret != LZMA_OK) > return false; > >diff --git a/src/journal/coredumpctl.c b/src/journal/coredumpctl.c >index 2158d73..ecde547 100644 >--- a/src/journal/coredumpctl.c >+++ b/src/journal/coredumpctl.c >@@ -595,7 +595,8 @@ static int save_core(sd_journal *j, int fd, char **path, bool *unlink_temp) { > retrieve(data, len, "COREDUMP_FILENAME", &filename); > > if (filename && access(filename, R_OK) < 0) { >- log_debug("File %s is not readable: %m", filename); >+ log_full(errno == ENOENT ? LOG_DEBUG : LOG_WARNING, >+ "File %s is not readable: %m", filename); > free(filename); > filename = NULL; > } >@@ -668,7 +669,7 @@ static int save_core(sd_journal *j, int fd, char **path, bool *unlink_temp) { > #endif > } else { > if (r == -ENOENT) >- log_error("Coredump neither in journal file nor stored externally on disk."); >+ log_error("Cannot retrieve coredump from journal nor disk."); > else > log_error("Failed to retrieve COREDUMP field: %s", strerror(-r)); > goto error; >diff --git a/src/journal/journal-file.c b/src/journal/journal-file.c >index b3b1ffc..ef54af4 100644 >--- a/src/journal/journal-file.c >+++ b/src/journal/journal-file.c >@@ -271,12 +271,6 @@ static int journal_file_verify_header(JournalFile *f) { > !VALID64(le64toh(f->header->entry_array_offset))) > return -ENODATA; > >- if (le64toh(f->header->data_hash_table_offset) < le64toh(f->header->header_size) || >- le64toh(f->header->field_hash_table_offset) < le64toh(f->header->header_size) || >- le64toh(f->header->tail_object_offset) < le64toh(f->header->header_size) || >- le64toh(f->header->entry_array_offset) < le64toh(f->header->header_size)) >- return -ENODATA; >- > if (f->writable) { > uint8_t state; > sd_id128_t machine_id; >diff --git a/src/journal/journald-native.c b/src/journal/journald-native.c >index c54f647..666cbd2 100644 >--- a/src/journal/journald-native.c >+++ b/src/journal/journald-native.c >@@ -387,7 +387,7 @@ int server_open_native_socket(Server*s) { > > r = bind(s->native_fd, &sa.sa, offsetof(union sockaddr_union, un.sun_path) + strlen(sa.un.sun_path)); > if (r < 0) { >- log_error("bind() failed: %m"); >+ log_error("bind(%s) failed: %m", sa.un.sun_path); > return -errno; > } > >diff --git a/src/journal/journald-stream.c b/src/journal/journald-stream.c >index 89da150..8a983d8 100644 >--- a/src/journal/journald-stream.c >+++ b/src/journal/journald-stream.c >@@ -450,14 +450,14 @@ int server_open_stdout_socket(Server *s) { > > r = bind(s->stdout_fd, &sa.sa, offsetof(union sockaddr_union, un.sun_path) + strlen(sa.un.sun_path)); > if (r < 0) { >- log_error("bind() failed: %m"); >+ log_error("bind(%s) failed: %m", sa.un.sun_path); > return -errno; > } > > chmod(sa.un.sun_path, 0666); > > if (listen(s->stdout_fd, SOMAXCONN) < 0) { >- log_error("listen() failed: %m"); >+ log_error("listen(%s) failed: %m", sa.un.sun_path); > return -errno; > } > } else >diff --git a/src/journal/journald-syslog.c b/src/journal/journald-syslog.c >index b826e23..f97e0d2 100644 >--- a/src/journal/journald-syslog.c >+++ b/src/journal/journald-syslog.c >@@ -441,7 +441,7 @@ int server_open_syslog_socket(Server *s) { > > r = bind(s->syslog_fd, &sa.sa, offsetof(union sockaddr_union, un.sun_path) + strlen(sa.un.sun_path)); > if (r < 0) { >- log_error("bind() failed: %m"); >+ log_error("bind(%s) failed: %m", sa.un.sun_path); > return -errno; > } > >diff --git a/src/journal/sd-journal.c b/src/journal/sd-journal.c >index ca805f8..15dae90 100644 >--- a/src/journal/sd-journal.c >+++ b/src/journal/sd-journal.c >@@ -2390,7 +2390,7 @@ _public_ int sd_journal_get_cutoff_realtime_usec(sd_journal *j, uint64_t *from, > _public_ int sd_journal_get_cutoff_monotonic_usec(sd_journal *j, sd_id128_t boot_id, uint64_t *from, uint64_t *to) { > Iterator i; > JournalFile *f; >- bool first = true; >+ bool found = false; > int r; > > assert_return(j, -EINVAL); >@@ -2409,21 +2409,21 @@ _public_ int sd_journal_get_cutoff_monotonic_usec(sd_journal *j, sd_id128_t boot > if (r == 0) > continue; > >- if (first) { >+ if (found) { > if (from) >- *from = fr; >+ *from = MIN(fr, *from); > if (to) >- *to = t; >- first = false; >+ *to = MAX(t, *to); > } else { > if (from) >- *from = MIN(fr, *from); >+ *from = fr; > if (to) >- *to = MAX(t, *to); >+ *to = t; >+ found = true; > } > } > >- return first ? 0 : 1; >+ return found; > } > > void journal_print_header(sd_journal *j) { >diff --git a/src/journal/test-journal-send.c b/src/journal/test-journal-send.c >index 3e986ed..45eb327 100644 >--- a/src/journal/test-journal-send.c >+++ b/src/journal/test-journal-send.c >@@ -72,7 +72,7 @@ int main(int argc, char *argv[]) { > "N_CPUS=%li", sysconf(_SC_NPROCESSORS_ONLN), > NULL); > >- sleep(10); >+ sleep(1); > > return 0; > } >diff --git a/src/libsystemd-network/sd-dhcp6-client.c b/src/libsystemd-network/sd-dhcp6-client.c >index 8fdbbfe..a83778e 100644 >--- a/src/libsystemd-network/sd-dhcp6-client.c >+++ b/src/libsystemd-network/sd-dhcp6-client.c >@@ -708,7 +708,8 @@ static int client_receive_reply(sd_dhcp6_client *client, DHCP6Message *reply, > return 0; > } > >- dhcp6_lease_clear_timers(&client->lease->ia); >+ if (client->lease) >+ dhcp6_lease_clear_timers(&client->lease->ia); > > client->lease = sd_dhcp6_lease_unref(client->lease); > client->lease = lease; >diff --git a/src/libsystemd/sd-path/sd-path.c b/src/libsystemd/sd-path/sd-path.c >index 7ade915..360c854 100644 >--- a/src/libsystemd/sd-path/sd-path.c >+++ b/src/libsystemd/sd-path/sd-path.c >@@ -22,6 +22,7 @@ > #include "path-util.h" > #include "strv.h" > #include "sd-path.h" >+#include "missing.h" > > static int from_environment(const char *envname, const char *fallback, const char **ret) { > assert(ret); >diff --git a/src/login/70-uaccess.rules b/src/login/70-uaccess.rules >index e1cf897..694df2c 100644 >--- a/src/login/70-uaccess.rules >+++ b/src/login/70-uaccess.rules >@@ -12,7 +12,7 @@ ENV{MAJOR}=="", GOTO="uaccess_end" > SUBSYSTEM=="usb", ENV{ID_USB_INTERFACES}=="*:060101:*", TAG+="uaccess" > > # Digicams with proprietary protocol >-ENV{ID_GPHOTO2}=="*?", TAG+="uaccess" >+ENV{ID_GPHOTO2}=="?*", TAG+="uaccess" > > # SCSI and USB scanners > ENV{libsane_matched}=="yes", TAG+="uaccess" >@@ -49,13 +49,13 @@ SUBSYSTEM=="drm", KERNEL=="card*|renderD*", TAG+="uaccess" > SUBSYSTEM=="misc", KERNEL=="kvm", TAG+="uaccess" > > # smart-card readers >-ENV{ID_SMARTCARD_READER}=="*?", TAG+="uaccess" >+ENV{ID_SMARTCARD_READER}=="?*", TAG+="uaccess" > > # (USB) authentication devices >-ENV{ID_SECURITY_TOKEN}=="*?", TAG+="uaccess" >+ENV{ID_SECURITY_TOKEN}=="?*", TAG+="uaccess" > > # PDA devices >-ENV{ID_PDA}=="*?", TAG+="uaccess" >+ENV{ID_PDA}=="?*", TAG+="uaccess" > > # Programmable remote control > ENV{ID_REMOTE_CONTROL}=="1", TAG+="uaccess" >@@ -64,12 +64,15 @@ ENV{ID_REMOTE_CONTROL}=="1", TAG+="uaccess" > SUBSYSTEM=="input", ENV{ID_INPUT_JOYSTICK}=="?*", TAG+="uaccess" > > # color measurement devices >-ENV{COLOR_MEASUREMENT_DEVICE}=="*?", TAG+="uaccess" >+ENV{COLOR_MEASUREMENT_DEVICE}=="?*", TAG+="uaccess" > > # DDC/CI device, usually high-end monitors such as the DreamColor >-ENV{DDC_DEVICE}=="*?", TAG+="uaccess" >+ENV{DDC_DEVICE}=="?*", TAG+="uaccess" > > # media player raw devices (for user-mode drivers, Android SDK, etc.) > SUBSYSTEM=="usb", ENV{ID_MEDIA_PLAYER}=="?*", TAG+="uaccess" > >+# software-defined radio communication devices >+ENV{ID_SOFTWARE_RADIO}=="?*", TAG+="uaccess" >+ > LABEL="uaccess_end" >diff --git a/src/login/logind-acl.c b/src/login/logind-acl.c >index 4bbeb64..af7c352 100644 >--- a/src/login/logind-acl.c >+++ b/src/login/logind-acl.c >@@ -277,7 +277,10 @@ int devnode_acl_all(struct udev *udev, > SET_FOREACH(n, nodes, i) { > int k; > >- log_debug("Fixing up ACLs at %s for seat %s", n, seat); >+ log_debug("Changing ACLs at %s for seat %s (uid "UID_FMT"â"UID_FMT"%s%s)", >+ n, seat, old_uid, new_uid, >+ del ? " del" : "", add ? " add" : ""); >+ > k = devnode_acl(n, flush, del, old_uid, add, new_uid); > if (k == -ENOENT) > log_debug("Device %s disappeared while setting ACLs", n); >diff --git a/src/login/logind-seat.c b/src/login/logind-seat.c >index 3114de8..9992195 100644 >--- a/src/login/logind-seat.c >+++ b/src/login/logind-seat.c >@@ -275,8 +275,13 @@ int seat_switch_to(Seat *s, unsigned int num) { > if (!num) > return -EINVAL; > >- if (num >= s->position_count || !s->positions[num]) >+ if (num >= s->position_count || !s->positions[num]) { >+ /* allow switching to unused VTs to trigger auto-activate */ >+ if (seat_has_vts(s) && num < 64) >+ return chvt(num); >+ > return -EINVAL; >+ } > > return session_activate(s->positions[num]); > } >diff --git a/src/machine/machine.c b/src/machine/machine.c >index c0fa1b2..cf38e3f 100644 >--- a/src/machine/machine.c >+++ b/src/machine/machine.c >@@ -371,7 +371,7 @@ static int machine_stop_scope(Machine *m) { > free(m->scope_job); > m->scope_job = job; > >- return r; >+ return 0; > } > > int machine_stop(Machine *m) { >diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c >index 14c0417..6257372 100644 >--- a/src/network/networkd-link.c >+++ b/src/network/networkd-link.c >@@ -599,10 +599,35 @@ static int route_drop_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) > return 0; > } > >+static int link_get_address_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) { >+ _cleanup_link_unref_ Link *link = userdata; >+ int r; >+ >+ assert(rtnl); >+ assert(m); >+ assert(link); >+ assert(link->manager); >+ >+ for (; m; m = sd_rtnl_message_next(m)) { >+ r = sd_rtnl_message_get_errno(m); >+ if (r < 0) { >+ log_debug_link(link, "getting address failed: %s", strerror(-r)); >+ continue; >+ } >+ >+ r = link_rtnl_process_address(rtnl, m, link->manager); >+ if (r < 0) >+ log_warning_link(link, "could not process address: %s", strerror(-r)); >+ } >+ >+ return 1; >+} >+ > static int address_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) { > _cleanup_link_unref_ Link *link = userdata; > int r; > >+ assert(rtnl); > assert(m); > assert(link); > assert(link->ifname); >@@ -623,6 +648,11 @@ static int address_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) { > link->ifname, strerror(-r), > "ERRNO=%d", -r, > NULL); >+ if (r >= 0) { >+ /* calling handler directly so take a ref */ >+ link_ref(link); >+ link_get_address_handler(rtnl, m, link); >+ } > > if (link->addr_messages == 0) { > log_debug_link(link, "addresses set"); >@@ -2140,7 +2170,7 @@ int link_rtnl_process_address(sd_rtnl *rtnl, sd_rtnl_message *message, void *use > > r = address_new_dynamic(&address); > if (r < 0) >- return 0; >+ return r; > > r = sd_rtnl_message_addr_get_family(message, &address->family); > if (r < 0 || !IN_SET(address->family, AF_INET, AF_INET6)) { >@@ -2204,7 +2234,10 @@ int link_rtnl_process_address(sd_rtnl *rtnl, sd_rtnl_message *message, void *use > case RTM_NEWADDR: > if (!address_dropped) > log_debug_link(link, "added address: %s/%u", buf, >- address->prefixlen); >+ address->prefixlen); >+ else >+ log_debug_link(link, "updated address: %s/%u", buf, >+ address->prefixlen); > > LIST_PREPEND(addresses, link->addresses, address); > address = NULL; >@@ -2215,10 +2248,12 @@ int link_rtnl_process_address(sd_rtnl *rtnl, sd_rtnl_message *message, void *use > case RTM_DELADDR: > if (address_dropped) { > log_debug_link(link, "removed address: %s/%u", buf, >- address->prefixlen); >+ address->prefixlen); > > link_save(link); >- } >+ } else >+ log_warning_link(link, "removing non-existent address: %s/%u", >+ buf, address->prefixlen); > > break; > default: >@@ -2228,30 +2263,6 @@ int link_rtnl_process_address(sd_rtnl *rtnl, sd_rtnl_message *message, void *use > return 1; > } > >-static int link_get_address_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) { >- _cleanup_link_unref_ Link *link = userdata; >- int r; >- >- assert(rtnl); >- assert(m); >- assert(link); >- assert(link->manager); >- >- for (; m; m = sd_rtnl_message_next(m)) { >- r = sd_rtnl_message_get_errno(m); >- if (r < 0) { >- log_debug_link(link, "getting address failed: %s", strerror(-r)); >- continue; >- } >- >- r = link_rtnl_process_address(rtnl, m, link->manager); >- if (r < 0) >- log_warning_link(link, "could not process address: %s", strerror(-r)); >- } >- >- return 1; >-} >- > int link_add(Manager *m, sd_rtnl_message *message, Link **ret) { > Link *link; > _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL; >diff --git a/src/network/networkd-macvlan.c b/src/network/networkd-macvlan.c >index 9227144..7c23426 100644 >--- a/src/network/networkd-macvlan.c >+++ b/src/network/networkd-macvlan.c >@@ -150,6 +150,8 @@ int netdev_create_macvlan(NetDev *netdev, Link *link, sd_rtnl_message_handler_t > return r; > } > >+ link_ref(link); >+ > log_debug_netdev(netdev, "creating netdev"); > > netdev->state = NETDEV_STATE_CREATING; >diff --git a/src/network/networkd-network.c b/src/network/networkd-network.c >index 9ab4f23..9f6de18 100644 >--- a/src/network/networkd-network.c >+++ b/src/network/networkd-network.c >@@ -92,7 +92,7 @@ static int network_load_one(Manager *manager, const char *filename) { > network->dhcp_routes = true; > network->dhcp_sendhost = true; > >- r = config_parse(NULL, filename, file, "Match\0Network\0Address\0Route\0DHCPv4\0", config_item_perf_lookup, >+ r = config_parse(NULL, filename, file, "Match\0Network\0Address\0Route\0DHCP\0DHCPv4\0", config_item_perf_lookup, > (void*) network_network_gperf_lookup, false, false, network); > if (r < 0) { > log_warning("Could not parse config file %s: %s", filename, strerror(-r)); >diff --git a/src/network/networkd-tunnel.c b/src/network/networkd-tunnel.c >index 7341487..5a244f6 100644 >--- a/src/network/networkd-tunnel.c >+++ b/src/network/networkd-tunnel.c >@@ -529,6 +529,8 @@ int netdev_create_tunnel(NetDev *netdev, Link *link, sd_rtnl_message_handler_t c > return r; > } > >+ link_ref(link); >+ > log_debug_netdev(netdev, "Creating tunnel netdev: %s", > netdev_kind_to_string(netdev->kind)); > >diff --git a/src/network/networkd-vlan.c b/src/network/networkd-vlan.c >index 1d812fd..8727b9f 100644 >--- a/src/network/networkd-vlan.c >+++ b/src/network/networkd-vlan.c >@@ -139,6 +139,8 @@ int netdev_create_vlan(NetDev *netdev, Link *link, sd_rtnl_message_handler_t cal > return r; > } > >+ link_ref(link); >+ > log_debug_netdev(netdev, "creating netdev"); > > netdev->state = NETDEV_STATE_CREATING; >diff --git a/src/network/networkd-vxlan.c b/src/network/networkd-vxlan.c >index 8832024..1604594 100644 >--- a/src/network/networkd-vxlan.c >+++ b/src/network/networkd-vxlan.c >@@ -154,6 +154,8 @@ int netdev_create_vxlan(NetDev *netdev, Link *link, sd_rtnl_message_handler_t ca > return r; > } > >+ link_ref(link); >+ > log_debug_netdev(netdev, "Creating vxlan netdev: %s", > netdev_kind_to_string(netdev->kind)); > >diff --git a/src/shared/architecture.c b/src/shared/architecture.c >index 7dd049a..dc45f35 100644 >--- a/src/shared/architecture.c >+++ b/src/shared/architecture.c >@@ -115,7 +115,6 @@ Architecture uname_architecture(void) { > #elif defined(__tilegx__) > { "tilegx", ARCHITECTURE_TILEGX }, > #elif defined(__cris__) >- { "cris", ARCHITECTURE_CRIS }, > { "crisv32", ARCHITECTURE_CRIS }, > #else > #error "Please register your architecture here!" >@@ -154,7 +153,9 @@ static const char *const architecture_table[_ARCHITECTURE_MAX] = { > [ARCHITECTURE_SPARC] = "sparc", > [ARCHITECTURE_SPARC64] = "sparc64", > [ARCHITECTURE_MIPS] = "mips", >+ [ARCHITECTURE_MIPS_LE] = "mips-le", > [ARCHITECTURE_MIPS64] = "mips64", >+ [ARCHITECTURE_MIPS64_LE] = "mips64-le", > [ARCHITECTURE_ALPHA] = "alpha", > [ARCHITECTURE_ARM] = "arm", > [ARCHITECTURE_ARM_BE] = "arm-be", >diff --git a/src/shared/ask-password-api.c b/src/shared/ask-password-api.c >index 5997a03..8d03f4a 100644 >--- a/src/shared/ask-password-api.c >+++ b/src/shared/ask-password-api.c >@@ -270,7 +270,7 @@ static int create_socket(char **name) { > > if (r < 0) { > r = -errno; >- log_error("bind() failed: %m"); >+ log_error("bind(%s) failed: %m", sa.un.sun_path); > goto fail; > } > >diff --git a/src/shared/base-filesystem.c b/src/shared/base-filesystem.c >index daaeaca..addd26c 100644 >--- a/src/shared/base-filesystem.c >+++ b/src/shared/base-filesystem.c >@@ -42,12 +42,13 @@ typedef struct BaseFilesystem { > } BaseFilesystem; > > static const BaseFilesystem table[] = { >- { "bin", 0, "usr/bin", NULL }, >- { "lib", 0, "usr/lib", NULL }, >- { "root", 0755, NULL, NULL }, >- { "sbin", 0, "usr/sbin", NULL }, >+ { "bin", 0, "usr/bin\0", NULL }, >+ { "lib", 0, "usr/lib\0", NULL }, >+ { "root", 0755, NULL, NULL }, >+ { "sbin", 0, "usr/sbin\0", NULL }, > #if defined(__i386__) || defined(__x86_64__) >- { "lib64", 0, "usr/lib/x86_64-linux-gnu\0usr/lib64", "ld-linux-x86-64.so.2" }, >+ { "lib64", 0, "usr/lib/x86_64-linux-gnu\0" >+ "usr/lib64\0", "ld-linux-x86-64.so.2" }, > #endif > }; > >diff --git a/src/shared/dropin.h b/src/shared/dropin.h >index 27a2b29..9c9742d 100644 >--- a/src/shared/dropin.h >+++ b/src/shared/dropin.h >@@ -21,6 +21,8 @@ > along with systemd; If not, see <http://www.gnu.org/licenses/>. > ***/ > >+#include "macro.h" >+ > int drop_in_file(const char *dir, const char *unit, unsigned level, > const char *name, char **_p, char **_q); > >@@ -28,4 +30,4 @@ int write_drop_in(const char *dir, const char *unit, unsigned level, > const char *name, const char *data); > > int write_drop_in_format(const char *dir, const char *unit, unsigned level, >- const char *name, const char *format, ...); >+ const char *name, const char *format, ...) _printf_(5, 6); >diff --git a/src/shared/env-util.c b/src/shared/env-util.c >index b2e4553..20b208f 100644 >--- a/src/shared/env-util.c >+++ b/src/shared/env-util.c >@@ -78,7 +78,9 @@ bool env_value_is_valid(const char *e) { > if (!utf8_is_valid(e)) > return false; > >- if (string_has_cc(e)) >+ /* bash allows tabs in environment variables, and so should >+ * we */ >+ if (string_has_cc(e, "\t")) > return false; > > /* POSIX says the overall size of the environment block cannot >diff --git a/src/shared/fileio-label.c b/src/shared/fileio-label.c >index 0711826..c3def3c 100644 >--- a/src/shared/fileio-label.c >+++ b/src/shared/fileio-label.c >@@ -25,12 +25,13 @@ > > #include "fileio-label.h" > #include "label.h" >+#include "util.h" > > int write_string_file_atomic_label(const char *fn, const char *line) { > int r; > > r = label_context_set(fn, S_IFREG); >- if (r < 0) >+ if (r < 0) > return r; > > write_string_file_atomic(fn, line); >@@ -44,7 +45,7 @@ int write_env_file_label(const char *fname, char **l) { > int r; > > r = label_context_set(fname, S_IFREG); >- if (r < 0) >+ if (r < 0) > return r; > > write_env_file(fname, l); >@@ -53,3 +54,18 @@ int write_env_file_label(const char *fname, char **l) { > > return r; > } >+ >+int fopen_temporary_label(const char *target, >+ const char *path, FILE **f, char **temp_path) { >+ int r; >+ >+ r = label_context_set(target, S_IFREG); >+ if (r < 0) >+ return r; >+ >+ r = fopen_temporary(path, f, temp_path); >+ >+ label_context_clear(); >+ >+ return r; >+} >diff --git a/src/shared/fileio-label.h b/src/shared/fileio-label.h >index fce4fe0..25fa351 100644 >--- a/src/shared/fileio-label.h >+++ b/src/shared/fileio-label.h >@@ -27,3 +27,5 @@ > > int write_string_file_atomic_label(const char *fn, const char *line); > int write_env_file_label(const char *fname, char **l); >+int fopen_temporary_label(const char *target, >+ const char *path, FILE **f, char **temp_path); >diff --git a/src/shared/fileio.c b/src/shared/fileio.c >index fb1c1bc..d22770b 100644 >--- a/src/shared/fileio.c >+++ b/src/shared/fileio.c >@@ -738,11 +738,11 @@ static void write_env_var(FILE *f, const char *v) { > p++; > fwrite(v, 1, p-v, f); > >- if (string_has_cc(p) || chars_intersect(p, WHITESPACE "\'\"\\`$")) { >+ if (string_has_cc(p, NULL) || chars_intersect(p, WHITESPACE SHELL_NEED_QUOTES)) { > fputc('\"', f); > > for (; *p; p++) { >- if (strchr("\'\"\\`$", *p)) >+ if (strchr(SHELL_NEED_ESCAPE, *p)) > fputc('\\', f); > > fputc(*p, f); >diff --git a/src/shared/generator.c b/src/shared/generator.c >index 5d5b6a0..414470b 100644 >--- a/src/shared/generator.c >+++ b/src/shared/generator.c >@@ -125,7 +125,7 @@ int generator_write_timeouts(const char *dir, const char *what, const char *wher > char *prefix, *postfix; > > prefix = strndupa(opts, start - opts - (start != opts)); >- postfix = timeout + len + (timeout[len] != '\0'); >+ postfix = timeout + len + (start == opts && timeout[len] != '\0'); > *filtered = strjoin(prefix, *postfix ? postfix : NULL, NULL); > if (!*filtered) > return log_oom(); >@@ -148,7 +148,7 @@ int generator_write_timeouts(const char *dir, const char *what, const char *wher > > return write_drop_in_format(dir, unit, 50, "device-timeout", > "# Automatically generated by %s\n\n" >- "[Unit]\nJobTimeoutSec=%u", >+ "[Unit]\nJobTimeoutSec=" USEC_FMT, > program_invocation_short_name, > u / USEC_PER_SEC); > } >diff --git a/src/shared/missing.h b/src/shared/missing.h >index f129f0b..2985285 100644 >--- a/src/shared/missing.h >+++ b/src/shared/missing.h >@@ -371,6 +371,27 @@ static inline int setns(int fd, int nstype) { > #define LOOP_CTL_GET_FREE 0x4C82 > #endif > >+#if !HAVE_DECL_IFLA_MACVLAN_FLAGS >+#define IFLA_MACVLAN_UNSPEC 0 >+#define IFLA_MACVLAN_MODE 1 >+#define IFLA_MACVLAN_FLAGS 2 >+#define __IFLA_MACVLAN_MAX 3 >+ >+#define IFLA_MACVLAN_MAX (__IFLA_MACVLAN_MAX - 1) >+#endif >+ >+#if !HAVE_DECL_IFLA_VTI_REMOTE >+#define IFLA_VTI_UNSPEC 0 >+#define IFLA_VTI_LINK 1 >+#define IFLA_VTI_IKEY 2 >+#define IFLA_VTI_OKEY 3 >+#define IFLA_VTI_LOCAL 4 >+#define IFLA_VTI_REMOTE 5 >+#define __IFLA_VTI_MAX 6 >+ >+#define IFLA_VTI_MAX (__IFLA_VTI_MAX - 1) >+#endif >+ > #if !HAVE_DECL_IFLA_PHYS_PORT_ID > #undef IFLA_PROMISCUITY > #define IFLA_PROMISCUITY 30 >diff --git a/src/shared/mkdir.h b/src/shared/mkdir.h >index d15ede6..dd5b41e 100644 >--- a/src/shared/mkdir.h >+++ b/src/shared/mkdir.h >@@ -22,6 +22,7 @@ > along with systemd; If not, see <http://www.gnu.org/licenses/>. > ***/ > >+#include <stdbool.h> > #include <sys/types.h> > > int mkdir_safe(const char *path, mode_t mode, uid_t uid, gid_t gid); >diff --git a/src/shared/path-lookup.c b/src/shared/path-lookup.c >index e0aaf44..7d53d85 100644 >--- a/src/shared/path-lookup.c >+++ b/src/shared/path-lookup.c >@@ -125,26 +125,8 @@ static char** user_dirs( > goto fail; > > } else if (home) { >- _cleanup_free_ char *data_home_parent = NULL; >- > if (asprintf(&data_home, "%s/.local/share/systemd/user", home) < 0) > goto fail; >- >- /* There is really no need for two unit dirs in $HOME, >- * except to be fully compliant with the XDG spec. We >- * now try to link the two dirs, so that we can >- * minimize disk seeks a little. Further down we'll >- * then filter out this link, if it is actually is >- * one. */ >- >- if (path_get_parent(data_home, &data_home_parent) >= 0) { >- _cleanup_free_ char *config_home_relative = NULL; >- >- if (path_make_relative(data_home_parent, config_home, &config_home_relative) >= 0) { >- mkdir_parents_label(data_home, 0777); >- (void) symlink(config_home_relative, data_home); >- } >- } > } > > e = getenv("XDG_DATA_DIRS"); >diff --git a/src/shared/util.c b/src/shared/util.c >index 3d875c7..03a5860 100644 >--- a/src/shared/util.c >+++ b/src/shared/util.c >@@ -1608,8 +1608,9 @@ int read_one_char(FILE *f, char *ret, usec_t t, bool *need_nl) { > return -ETIMEDOUT; > } > >+ errno = 0; > if (!fgets(line, sizeof(line), f)) >- return -EIO; >+ return errno ? -errno : -EIO; > > truncate_nl(line); > >@@ -5349,13 +5350,14 @@ bool filename_is_safe(const char *p) { > bool string_is_safe(const char *p) { > const char *t; > >- assert(p); >+ if (!p) >+ return false; > > for (t = p; *t; t++) { > if (*t > 0 && *t < ' ') > return false; > >- if (strchr("\\\"\'", *t)) >+ if (strchr("\\\"\'\0x7f", *t)) > return false; > } > >@@ -5363,18 +5365,25 @@ bool string_is_safe(const char *p) { > } > > /** >- * Check if a string contains control characters. >- * Spaces and tabs are not considered control characters. >+ * Check if a string contains control characters. If 'ok' is non-NULL >+ * it may be a string containing additional CCs to be considered OK. > */ >-bool string_has_cc(const char *p) { >+bool string_has_cc(const char *p, const char *ok) { > const char *t; > > assert(p); > >- for (t = p; *t; t++) >- if (*t > 0 && *t < ' ' && *t != '\t') >+ for (t = p; *t; t++) { >+ if (ok && strchr(ok, *t)) >+ continue; >+ >+ if (*t > 0 && *t < ' ') > return true; > >+ if (*t == 127) >+ return true; >+ } >+ > return false; > } > >diff --git a/src/shared/util.h b/src/shared/util.h >index e23069c..64b9fc6 100644 >--- a/src/shared/util.h >+++ b/src/shared/util.h >@@ -93,6 +93,12 @@ > #define COMMENTS "#;" > #define GLOB_CHARS "*?[" > >+/* What characters are special in the shell? */ >+/* must be escaped outside and inside double-quotes */ >+#define SHELL_NEED_ESCAPE "\"\\`$" >+/* can be escaped or double-quoted */ >+#define SHELL_NEED_QUOTES SHELL_NEED_ESCAPE GLOB_CHARS "'()<>|&;" >+ > #define FORMAT_BYTES_MAX 8 > > #define ANSI_HIGHLIGHT_ON "\x1B[1;39m" >@@ -692,7 +698,7 @@ _alloc_(2, 3) static inline void *memdup_multiply(const void *p, size_t a, size_ > bool filename_is_safe(const char *p) _pure_; > bool path_is_safe(const char *p) _pure_; > bool string_is_safe(const char *p) _pure_; >-bool string_has_cc(const char *p) _pure_; >+bool string_has_cc(const char *p, const char *ok) _pure_; > > /** > * Check if a string contains any glob patterns. >diff --git a/src/shared/virt.c b/src/shared/virt.c >index 774915f..b436895 100644 >--- a/src/shared/virt.c >+++ b/src/shared/virt.c >@@ -173,7 +173,7 @@ int detect_vm(const char **id) { > if (streq(cap, "control_d")) > break; > >- if (!i) { >+ if (!cap) { > _id = "xen"; > r = 1; > } >@@ -220,6 +220,23 @@ int detect_vm(const char **id) { > goto finish; > } > >+#if defined(__s390__) >+ { >+ _cleanup_free_ char *t = NULL; >+ >+ r = get_status_field("/proc/sysinfo", "VM00 Control Program:", &t); >+ if (r >= 0) { >+ if (streq(t, "z/VM")) >+ _id = "zvm"; >+ else >+ _id = "kvm"; >+ r = 1; >+ >+ goto finish; >+ } >+ } >+#endif >+ > r = 0; > > finish: >diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c >index 03720f4..8086e1e 100644 >--- a/src/systemctl/systemctl.c >+++ b/src/systemctl/systemctl.c >@@ -456,7 +456,7 @@ static int output_units_list(const UnitInfo *unit_infos, unsigned c) { > } > > if (circle_len > 0) >- printf("%s%s%s", on_circle, circle ? draw_special_char(DRAW_BLACK_CIRCLE) : " ", off_circle); >+ printf("%s%s%s ", on_circle, circle ? draw_special_char(DRAW_BLACK_CIRCLE) : " ", off_circle); > > printf("%s%-*s%s %s%-*s%s %s%-*s %-*s%s %-*s", > on_active, id_len, id, off_active, >diff --git a/src/sysusers/sysusers.c b/src/sysusers/sysusers.c >index 1209a5a..2387d58 100644 >--- a/src/sysusers/sysusers.c >+++ b/src/sysusers/sysusers.c >@@ -24,6 +24,7 @@ > #include <grp.h> > #include <shadow.h> > #include <getopt.h> >+#include <utmp.h> > > #include "util.h" > #include "hashmap.h" >@@ -34,6 +35,8 @@ > #include "conf-files.h" > #include "copy.h" > #include "utf8.h" >+#include "label.h" >+#include "fileio-label.h" > > typedef enum ItemType { > ADD_USER = 'u', >@@ -61,6 +64,8 @@ typedef struct Item { > static char *arg_root = NULL; > > static const char conf_file_dirs[] = >+ "/etc/sysusers.d\0" >+ "/run/sysusers.d\0" > "/usr/local/lib/sysusers.d\0" > "/usr/lib/sysusers.d\0" > #ifdef HAVE_SPLIT_USR >@@ -190,8 +195,9 @@ static int load_group_database(void) { > return 0; > } > >-static int make_backup(const char *x) { >- _cleanup_close_ int src = -1, dst = -1; >+static int make_backup(const char *target, const char *x) { >+ _cleanup_close_ int src = -1; >+ _cleanup_fclose_ FILE *dst = NULL; > char *backup, *temp; > struct timespec ts[2]; > struct stat st; >@@ -208,30 +214,30 @@ static int make_backup(const char *x) { > if (fstat(src, &st) < 0) > return -errno; > >- temp = strappenda(x, ".XXXXXX"); >- dst = mkostemp_safe(temp, O_WRONLY|O_CLOEXEC|O_NOCTTY); >- if (dst < 0) >- return dst; >+ r = fopen_temporary_label(target, x, &dst, &temp); >+ if (r < 0) >+ return r; > >- r = copy_bytes(src, dst, (off_t) -1); >+ r = copy_bytes(src, fileno(dst), (off_t) -1); > if (r < 0) > goto fail; > >+ /* Don't fail on chmod() or chown(). If it stays owned by us >+ * and/or unreadable by others, then it isn't too bad... */ >+ >+ backup = strappenda(x, "-"); >+ > /* Copy over the access mask */ >- if (fchmod(dst, st.st_mode & 07777) < 0) { >- r = -errno; >- goto fail; >- } >+ if (fchmod(fileno(dst), st.st_mode & 07777) < 0) >+ log_warning("Failed to change mode on %s: %m", backup); > >- /* Don't fail on chmod(). If it stays owned by us, then it >- * isn't too bad... */ >- fchown(dst, st.st_uid, st.st_gid); >+ if (fchown(fileno(dst), st.st_uid, st.st_gid)< 0) >+ log_warning("Failed to change ownership of %s: %m", backup); > > ts[0] = st.st_atim; > ts[1] = st.st_mtim; >- futimens(dst, ts); >+ futimens(fileno(dst), ts); > >- backup = strappenda(x, "-"); > if (rename(temp, backup) < 0) > goto fail; > >@@ -309,7 +315,7 @@ static int write_files(void) { > _cleanup_fclose_ FILE *original = NULL; > > group_path = fix_root("/etc/group"); >- r = fopen_temporary(group_path, &group, &group_tmp); >+ r = fopen_temporary_label("/etc/group", group_path, &group, &group_tmp); > if (r < 0) > goto finish; > >@@ -385,7 +391,7 @@ static int write_files(void) { > _cleanup_fclose_ FILE *original = NULL; > > passwd_path = fix_root("/etc/passwd"); >- r = fopen_temporary(passwd_path, &passwd, &passwd_tmp); >+ r = fopen_temporary_label("/etc/passwd", passwd_path, &passwd, &passwd_tmp); > if (r < 0) > goto finish; > >@@ -464,13 +470,13 @@ static int write_files(void) { > > /* Make a backup of the old files */ > if (group && group_changed) { >- r = make_backup(group_path); >+ r = make_backup("/etc/group", group_path); > if (r < 0) > goto finish; > } > > if (passwd) { >- r = make_backup(passwd_path); >+ r = make_backup("/etc/passwd", passwd_path); > if (r < 0) > goto finish; > } >@@ -1095,6 +1101,9 @@ static bool valid_user_group_name(const char *u) { > if ((size_t) (i-u) > (size_t) sz) > return false; > >+ if ((size_t) (i-u) > UT_NAMESIZE - 1) >+ return false; >+ > return true; > } > >@@ -1103,7 +1112,11 @@ static bool valid_gecos(const char *d) { > if (!utf8_is_valid(d)) > return false; > >- if (strpbrk(d, ":\n")) >+ if (string_has_cc(d, NULL)) >+ return false; >+ >+ /* Colons are used as field separators, and hence not OK */ >+ if (strchr(d, ':')) > return false; > > return true; >@@ -1312,6 +1325,8 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) { > > h = groups; > break; >+ default: >+ return -EBADMSG; > } > > i->type = action[0]; >@@ -1515,7 +1530,11 @@ int main(int argc, char *argv[]) { > > umask(0022); > >- r = 0; >+ r = label_init(NULL); >+ if (r < 0) { >+ log_error("SELinux setup failed: %s", strerror(-r)); >+ goto finish; >+ } > > if (optind < argc) { > int j; >diff --git a/src/test/test-util.c b/src/test/test-util.c >index 44921bd..ed91a67 100644 >--- a/src/test/test-util.c >+++ b/src/test/test-util.c >@@ -731,6 +731,20 @@ static void test_filename_is_safe(void) { > assert_se(filename_is_safe("o.o")); > } > >+static void test_string_has_cc(void) { >+ assert_se(string_has_cc("abc\1", NULL)); >+ assert_se(string_has_cc("abc\x7f", NULL)); >+ assert_se(string_has_cc("abc\x7f", NULL)); >+ assert_se(string_has_cc("abc\t\x7f", "\t")); >+ assert_se(string_has_cc("abc\t\x7f", "\t")); >+ assert_se(string_has_cc("\x7f", "\t")); >+ assert_se(string_has_cc("\x7f", "\t\a")); >+ >+ assert_se(!string_has_cc("abc\t\t", "\t")); >+ assert_se(!string_has_cc("abc\t\t\a", "\t\a")); >+ assert_se(!string_has_cc("a\ab\tc", "\t\a")); >+} >+ > static void test_ascii_strlower(void) { > char a[] = "AabBcC Jk Ii Od LKJJJ kkd LK"; > assert_se(streq(ascii_strlower(a), "aabbcc jk ii od lkjjj kkd lk")); >@@ -937,6 +951,7 @@ int main(int argc, char *argv[]) { > test_log2i(); > test_foreach_string(); > test_filename_is_safe(); >+ test_string_has_cc(); > test_ascii_strlower(); > test_files_same(); > test_is_valid_documentation_url(); >diff --git a/src/timesync/timesyncd.c b/src/timesync/timesyncd.c >index 27f6b2d..19af9f9 100644 >--- a/src/timesync/timesyncd.c >+++ b/src/timesync/timesyncd.c >@@ -1044,10 +1044,6 @@ static int manager_new(Manager **ret) { > if (r < 0) > return r; > >- r = manager_clock_watch_setup(m); >- if (r < 0) >- return r; >- > *ret = m; > m = NULL; > >diff --git a/src/udev/accelerometer/accelerometer.c b/src/udev/accelerometer/accelerometer.c >index 925d38d..32adf27 100644 >--- a/src/udev/accelerometer/accelerometer.c >+++ b/src/udev/accelerometer/accelerometer.c >@@ -180,7 +180,7 @@ get_prev_orientation(struct udev_device *dev) > return string_to_orientation(value); > } > >-#define SET_AXIS(axis, code_) if (ev[i].code == code_) { if (got_##axis == 0) { axis = ev[i].value; got_##axis = true; } } >+#define READ_AXIS(axis, var) { memzero(&abs_info, sizeof(abs_info)); r = ioctl(fd, EVIOCGABS(axis), &abs_info); if (r < 0) return; var = abs_info.value; } > > /* accelerometers */ > static void test_orientation(struct udev *udev, >@@ -189,10 +189,9 @@ static void test_orientation(struct udev *udev, > { > OrientationUp old, new; > _cleanup_close_ int fd = -1; >- struct input_event ev[64]; >- bool got_syn = false; >- bool got_x = false, got_y = false, got_z = false; >+ struct input_absinfo abs_info; > int x = 0, y = 0, z = 0; >+ int r; > char text[64]; > > old = get_prev_orientation(dev); >@@ -201,30 +200,10 @@ static void test_orientation(struct udev *udev, > if (fd < 0) > return; > >- while (1) { >- int i, r; >- >- r = read(fd, ev, sizeof(struct input_event) * 64); >- >- if (r < (int) sizeof(struct input_event)) >- return; >- >- for (i = 0; i < r / (int) sizeof(struct input_event); i++) { >- if (got_syn) { >- if (ev[i].type == EV_ABS) { >- SET_AXIS(x, ABS_X); >- SET_AXIS(y, ABS_Y); >- SET_AXIS(z, ABS_Z); >- } >- } >- if (ev[i].type == EV_SYN && ev[i].code == SYN_REPORT) >- got_syn = true; >- if (got_x && got_y && got_z) >- goto read_dev; >- } >- } >+ READ_AXIS(ABS_X, x); >+ READ_AXIS(ABS_Y, y); >+ READ_AXIS(ABS_Z, z); > >-read_dev: > new = orientation_calc(old, x, y, z); > snprintf(text, sizeof(text), > "ID_INPUT_ACCELEROMETER_ORIENTATION=%s", orientation_to_string(new)); >diff --git a/src/udev/net/link-config.c b/src/udev/net/link-config.c >index b8650a6..5a45c53 100644 >--- a/src/udev/net/link-config.c >+++ b/src/udev/net/link-config.c >@@ -383,7 +383,9 @@ int link_config_apply(link_config_ctx *ctx, link_config *config, struct udev_dev > case MACPOLICY_PERSISTENT: > if (mac_is_random(device)) { > r = get_mac(device, false, &generated_mac); >- if (r < 0) >+ if (r == -ENOENT) >+ break; >+ else if (r < 0) > return r; > mac = &generated_mac; > } >@@ -391,7 +393,9 @@ int link_config_apply(link_config_ctx *ctx, link_config *config, struct udev_dev > case MACPOLICY_RANDOM: > if (!mac_is_random(device)) { > r = get_mac(device, true, &generated_mac); >- if (r < 0) >+ if (r == -ENOENT) >+ break; >+ else if (r < 0) > return r; > mac = &generated_mac; > } >diff --git a/src/update-done/update-done.c b/src/update-done/update-done.c >index 10ba85c..b199a68 100644 >--- a/src/update-done/update-done.c >+++ b/src/update-done/update-done.c >@@ -20,6 +20,7 @@ > ***/ > > #include "util.h" >+#include "label.h" > > static int apply_timestamp(const char *path, struct timespec *ts) { > struct timespec twice[2]; >@@ -51,10 +52,20 @@ static int apply_timestamp(const char *path, struct timespec *ts) { > > } else if (errno == ENOENT) { > _cleanup_close_ int fd = -1; >+ int r; > > /* The timestamp file doesn't exist yet? Then let's create it. */ > >+ r = label_context_set(path, S_IFREG); >+ if (r < 0) { >+ log_error("Failed to set SELinux context for %s: %s", >+ path, strerror(-r)); >+ return r; >+ } >+ > fd = open(path, O_CREAT|O_EXCL|O_WRONLY|O_TRUNC|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW, 0644); >+ label_context_clear(); >+ > if (fd < 0) { > > if (errno == EROFS) { >@@ -83,7 +94,7 @@ static int apply_timestamp(const char *path, struct timespec *ts) { > > int main(int argc, char *argv[]) { > struct stat st; >- int r, q; >+ int r, q = 0; > > log_set_target(LOG_TARGET_AUTO); > log_parse_environment(); >@@ -94,11 +105,15 @@ int main(int argc, char *argv[]) { > return EXIT_FAILURE; > } > >- r = apply_timestamp("/etc/.updated", &st.st_mtim); >+ r = label_init(NULL); >+ if (r < 0) { >+ log_error("SELinux setup failed: %s", strerror(-r)); >+ goto finish; >+ } > >+ r = apply_timestamp("/etc/.updated", &st.st_mtim); > q = apply_timestamp("/var/.updated", &st.st_mtim); >- if (q < 0 && r == 0) >- r = q; > >- return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS; >+finish: >+ return r < 0 || q < 0 ? EXIT_FAILURE : EXIT_SUCCESS; > } >diff --git a/src/vconsole/vconsole-setup.c b/src/vconsole/vconsole-setup.c >index e0c4050..645b1e6 100644 >--- a/src/vconsole/vconsole-setup.c >+++ b/src/vconsole/vconsole-setup.c >@@ -238,12 +238,10 @@ static void font_copy_to_all_vcs(int fd) { > > int main(int argc, char **argv) { > const char *vc; >- char *vc_keymap = NULL; >- char *vc_keymap_toggle = NULL; >- char *vc_font = NULL; >- char *vc_font_map = NULL; >- char *vc_font_unimap = NULL; >- int fd = -1; >+ _cleanup_free_ char >+ *vc_keymap = NULL, *vc_keymap_toggle = NULL, >+ *vc_font = NULL, *vc_font_map = NULL, *vc_font_unimap = NULL; >+ _cleanup_close_ int fd = -1; > bool utf8; > pid_t font_pid = 0, keymap_pid = 0; > bool font_copy = false; >@@ -265,12 +263,12 @@ int main(int argc, char **argv) { > fd = open_terminal(vc, O_RDWR|O_CLOEXEC); > if (fd < 0) { > log_error("Failed to open %s: %m", vc); >- goto finish; >+ return EXIT_FAILURE; > } > > if (!is_vconsole(fd)) { > log_error("Device %s is not a virtual console.", vc); >- goto finish; >+ return EXIT_FAILURE; > } > > utf8 = is_locale_utf8(); >@@ -305,27 +303,27 @@ int main(int argc, char **argv) { > else > disable_utf8(fd); > >- r = EXIT_FAILURE; >- if (keymap_load(vc, vc_keymap, vc_keymap_toggle, utf8, &keymap_pid) >= 0 && >- font_load(vc, vc_font, vc_font_map, vc_font_unimap, &font_pid) >= 0) >- r = EXIT_SUCCESS; >- >-finish: >- if (keymap_pid > 0) >- wait_for_terminate_and_warn(KBD_LOADKEYS, keymap_pid); >+ r = font_load(vc, vc_font, vc_font_map, vc_font_unimap, &font_pid); >+ if (r < 0) { >+ log_error("Failed to start " KBD_SETFONT ": %s", strerror(-r)); >+ return EXIT_FAILURE; >+ } > >- if (font_pid > 0) { >+ if (font_pid > 0) > wait_for_terminate_and_warn(KBD_SETFONT, font_pid); >- if (font_copy) >- font_copy_to_all_vcs(fd); >+ >+ r = keymap_load(vc, vc_keymap, vc_keymap_toggle, utf8, &keymap_pid); >+ if (r < 0) { >+ log_error("Failed to start " KBD_LOADKEYS ": %s", strerror(-r)); >+ return EXIT_FAILURE; > } > >- free(vc_keymap); >- free(vc_font); >- free(vc_font_map); >- free(vc_font_unimap); >+ if (keymap_pid > 0) >+ wait_for_terminate_and_warn(KBD_LOADKEYS, keymap_pid); > >- safe_close(fd); >+ /* Only copy the font when we started setfont successfully */ >+ if (font_copy && font_pid > 0) >+ font_copy_to_all_vcs(fd); > >- return r; >+ return EXIT_SUCCESS; > } >diff --git a/sysctl.d/50-coredump.conf.in b/sysctl.d/50-coredump.conf.in >index d5795a3..d5f600e 100644 >--- a/sysctl.d/50-coredump.conf.in >+++ b/sysctl.d/50-coredump.conf.in >@@ -5,6 +5,8 @@ > # the Free Software Foundation; either version 2.1 of the License, or > # (at your option) any later version. > >-# See sysctl.d(5) and core(5) for for details. >+# See sysctl.d(5) for the description of the files in this directory, >+# and systemd-coredump(8) and core(5) for the explanation of the >+# setting below. > > kernel.core_pattern=|@rootlibexecdir@/systemd-coredump %p %u %g %s %t %e >diff --git a/units/emergency.service.in b/units/emergency.service.in >index 94c090f..91fc1bb 100644 >--- a/units/emergency.service.in >+++ b/units/emergency.service.in >@@ -17,8 +17,7 @@ Environment=HOME=/root > WorkingDirectory=/root > ExecStartPre=-/bin/plymouth quit > ExecStartPre=-/bin/echo -e 'Welcome to emergency mode! After logging in, type "journalctl -xb" to view\\nsystem logs, "systemctl reboot" to reboot, "systemctl default" to try again\\nto boot into default mode.' >-ExecStart=-/sbin/sulogin >-ExecStopPost=@SYSTEMCTL@ --fail --no-block default >+ExecStart=-/bin/sh -c "/sbin/sulogin; @SYSTEMCTL@ --fail --no-block default" > Type=idle > StandardInput=tty-force > StandardOutput=inherit >diff --git a/units/kmod-static-nodes.service.in b/units/kmod-static-nodes.service.in >index 368f980..0934a87 100644 >--- a/units/kmod-static-nodes.service.in >+++ b/units/kmod-static-nodes.service.in >@@ -9,7 +9,7 @@ > Description=Create list of required static device nodes for the current kernel > DefaultDependencies=no > Before=sysinit.target systemd-tmpfiles-setup-dev.service >-ConditionCapability=CAP_MKNOD >+ConditionCapability=CAP_SYS_MODULE > ConditionPathExists=/lib/modules/%v/modules.devname > > [Service] >diff --git a/units/rescue.service.m4.in b/units/rescue.service.m4.in >index 552ef89..ef54369 100644 >--- a/units/rescue.service.m4.in >+++ b/units/rescue.service.m4.in >@@ -18,8 +18,7 @@ Environment=HOME=/root > WorkingDirectory=/root > ExecStartPre=-/bin/plymouth quit > ExecStartPre=-/bin/echo -e 'Welcome to rescue mode! Type "systemctl default" or ^D to enter default mode.\\nType "journalctl -xb" to view system logs. Type "systemctl reboot" to reboot.' >-ExecStart=-/sbin/sulogin >-ExecStopPost=-@SYSTEMCTL@ --fail --no-block default >+ExecStart=-/bin/sh -c "/sbin/sulogin; @SYSTEMCTL@ --fail --no-block default" > Type=idle > StandardInput=tty-force > StandardOutput=inherit >diff --git a/units/serial-getty@.service.m4 b/units/serial-getty@.service.m4 >index 4ac51e7..4522d0d 100644 >--- a/units/serial-getty@.service.m4 >+++ b/units/serial-getty@.service.m4 >@@ -25,7 +25,6 @@ IgnoreOnIsolate=yes > ExecStart=-/sbin/agetty --keep-baud 115200,38400,9600 %I $TERM > Type=idle > Restart=always >-RestartSec=0 > UtmpIdentifier=%I > TTYPath=/dev/%I > TTYReset=yes >diff --git a/units/sys-kernel-config.mount b/units/sys-kernel-config.mount >index 020101c..21648ef 100644 >--- a/units/sys-kernel-config.mount >+++ b/units/sys-kernel-config.mount >@@ -11,6 +11,7 @@ Documentation=https://www.kernel.org/doc/Documentation/filesystems/configfs/conf > Documentation=http://www.freedesktop.org/wiki/Software/systemd/APIFileSystems > DefaultDependencies=no > ConditionPathExists=/sys/kernel/config >+ConditionCapability=CAP_SYS_RAWIO > After=systemd-modules-load.service > Before=sysinit.target > >diff --git a/units/sys-kernel-debug.mount b/units/sys-kernel-debug.mount >index 5369728..1e94387 100644 >--- a/units/sys-kernel-debug.mount >+++ b/units/sys-kernel-debug.mount >@@ -11,6 +11,7 @@ Documentation=https://www.kernel.org/doc/Documentation/filesystems/debugfs.txt > Documentation=http://www.freedesktop.org/wiki/Software/systemd/APIFileSystems > DefaultDependencies=no > ConditionPathExists=/sys/kernel/debug >+ConditionCapability=CAP_SYS_RAWIO > Before=sysinit.target > > [Mount] >diff --git a/units/systemd-tmpfiles-setup-dev.service.in b/units/systemd-tmpfiles-setup-dev.service.in >index b9cfc53..06346d3 100644 >--- a/units/systemd-tmpfiles-setup-dev.service.in >+++ b/units/systemd-tmpfiles-setup-dev.service.in >@@ -12,7 +12,7 @@ DefaultDependencies=no > Conflicts=shutdown.target > After=systemd-readahead-collect.service systemd-readahead-replay.service systemd-sysusers.service > Before=sysinit.target local-fs-pre.target systemd-udevd.service shutdown.target >-ConditionCapability=CAP_MKNOD >+ConditionCapability=CAP_SYS_MODULE > > [Service] > Type=oneshot
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 519418
: 382532