]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
Merge pull request #5449 from keszybz/blkd-error-handling
authorMartin Pitt <martinpitt@users.noreply.github.com>
Sat, 25 Feb 2017 11:25:27 +0000 (12:25 +0100)
committerGitHub <noreply@github.com>
Sat, 25 Feb 2017 11:25:27 +0000 (12:25 +0100)
blkid error handling

66 files changed:
NEWS
configure.ac
hwdb/70-pointingstick.hwdb
man/coredumpctl.xml
man/journalctl.xml
man/kernel-command-line.xml
man/systemd.exec.xml
man/systemd.xml
shell-completion/bash/coredumpctl
shell-completion/zsh/_coredumpctl
src/basic/build.h
src/basic/cgroup-util.c
src/basic/cgroup-util.h
src/basic/copy.c
src/basic/def.h
src/basic/env-util.c
src/basic/fileio.c
src/basic/fs-util.h
src/basic/khash.h
src/basic/log.c
src/basic/log.h
src/basic/proc-cmdline.c
src/basic/process-util.c
src/basic/strv.c
src/boot/bootctl.c
src/boot/efi/boot.c
src/cgls/cgls.c
src/cgtop/cgtop.c
src/core/cgroup.c
src/core/main.c
src/core/manager.c
src/core/mount-setup.c
src/core/namespace.c
src/core/scope.c
src/core/service.c
src/core/socket.c
src/core/unit.c
src/coredump/coredumpctl.c
src/dissect/dissect.c
src/import/curl-util.c
src/journal/journal-file.c
src/journal/journald-server.c
src/journal/test-compress.c
src/libsystemd-network/arp-util.c
src/libsystemd-network/test-lldp.c
src/libsystemd/sd-bus/test-bus-creds.c
src/libsystemd/sd-device/device-internal.h
src/libsystemd/sd-netlink/netlink-socket.c
src/libsystemd/sd-netlink/sd-netlink.c
src/libsystemd/sd-network/sd-network.c
src/mount/mount-tool.c
src/network/networkd-address.c
src/network/networkd-route.c
src/nspawn/nspawn-cgroup.c
src/nspawn/nspawn-mount.c
src/nspawn/nspawn.c
src/resolve/resolved-dns-answer.c
src/resolve/resolved-dns-cache.c
src/resolve/resolved-dns-transaction.c
src/resolve/resolved-link.c
src/shared/fstab-util.c
src/shared/machine-image.c
src/test/test-cgroup-util.c
src/test/test-dns-domain.c
src/test/test-env-util.c
src/tmpfiles/tmpfiles.c

diff --git a/NEWS b/NEWS
index 954a83a0b6eeae6e310530ee0a788a704254a68b..a3b3fef62768ff9c0f677d6dd8c11cd2dcf3f160 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -357,6 +357,13 @@ CHANGES WITH 233 in spe
 
 CHANGES WITH 232:
 
+        * udev now runs with MemoryDenyWriteExecute=, RestrictRealtime= and
+          RestrictAddressFamilies= enabled. These sandboxing options should
+          generally be compatible with the various external udev call-out
+          binaries we are aware of, however there may be exceptions, in
+          particular when exotic languages for these call-outs are used. In
+          this case, consider turning off these settings locally.
+
         * The new RemoveIPC= option can be used to remove IPC objects owned by
           the user or group of a service when that service exits.
 
index 156511851cd92ceb599f89499de4ce66f180877a..d98cc4d9bad4d538f512bc1c7f7193b7c9093571 100644 (file)
@@ -612,6 +612,23 @@ AC_ARG_WITH([fallback-hostname],
 AC_SUBST(FALLBACK_HOSTNAME)
 AC_DEFINE_UNQUOTED(FALLBACK_HOSTNAME, ["$FALLBACK_HOSTNAME"], [The hostname used if none configured])
 
+# ------------------------------------------------------------------------------
+
+AC_ARG_WITH(default-hierarchy,
+        AS_HELP_STRING([--with-default-hierarchy=MODE],
+                [default cgroup hierarchy, defaults to "hybrid"]),
+        [DEFAULT_HIERARCHY="$withval"],
+        [DEFAULT_HIERARCHY="hybrid"])
+
+AS_CASE("$DEFAULT_HIERARCHY",
+        [legacy], [mode=CGROUP_UNIFIED_NONE],
+        [hybrid], [mode=CGROUP_UNIFIED_SYSTEMD],
+        [unified], [mode=CGROUP_UNIFIED_ALL],
+        AC_MSG_ERROR(Bad default hierarchy mode ${DEFAULT_HIERARCHY}))
+AC_DEFINE_UNQUOTED(DEFAULT_HIERARCHY, [$mode], [Default cgroup hierarchy])
+AC_DEFINE_UNQUOTED(DEFAULT_HIERARCHY_NAME, ["$DEFAULT_HIERARCHY"],
+                                           [Default cgroup hierarchy as string])
+
 # ------------------------------------------------------------------------------
 have_xz=no
 AC_ARG_ENABLE(xz, AS_HELP_STRING([--disable-xz], [disable optional XZ support]))
@@ -1667,19 +1684,20 @@ AC_MSG_RESULT([
         backlight:                         ${have_backlight}
         rfkill:                            ${have_rfkill}
         logind:                            ${have_logind}
-        Default KillUserProcesses setting: ${KILL_USER_PROCESSES}
+        default cgroup hierarchy:          ${DEFAULT_HIERARCHY}
+        default KillUserProcesses setting: ${KILL_USER_PROCESSES}
         machined:                          ${have_machined}
         importd:                           ${have_importd}
         hostnamed:                         ${have_hostnamed}
         timedated:                         ${have_timedated}
         timesyncd:                         ${have_timesyncd}
-        Default NTP servers:               ${NTP_SERVERS}
+        default NTP servers:               ${NTP_SERVERS}
         time epoch:                        ${TIME_EPOCH}
         localed:                           ${have_localed}
         networkd:                          ${have_networkd}
         resolved:                          ${have_resolved}
-        Default DNS servers:               ${DNS_SERVERS}
-        Default DNSSEC mode:               ${DEFAULT_DNSSEC_MODE}
+        default DNS servers:               ${DNS_SERVERS}
+        default DNSSEC mode:               ${DEFAULT_DNSSEC_MODE}
         coredump:                          ${have_coredump}
         polkit:                            ${have_polkit}
         efi:                               ${have_efi}
@@ -1718,27 +1736,27 @@ AC_MSG_RESULT([
         rootlib dir:                       ${with_rootlibdir}
         SysV init scripts:                 ${SYSTEM_SYSVINIT_PATH}
         SysV rc?.d directories:            ${SYSTEM_SYSVRCND_PATH}
-        Build Python:                      ${PYTHON}
+        build Python:                      ${PYTHON}
         PAM modules dir:                   ${with_pamlibdir}
         PAM configuration dir:             ${with_pamconfdir}
         D-Bus policy dir:                  ${with_dbuspolicydir}
         D-Bus session dir:                 ${with_dbussessionservicedir}
         D-Bus system dir:                  ${with_dbussystemservicedir}
-        Bash completions dir:              ${with_bashcompletiondir}
-        Zsh completions dir:               ${with_zshcompletiondir}
-        Extra start script:                ${RC_LOCAL_SCRIPT_PATH_START}
-        Extra stop script:                 ${RC_LOCAL_SCRIPT_PATH_STOP}
-        Adm group:                         ${have_adm_group}
-        Wheel group:                       ${have_wheel_group}
-        Debug shell:                       ${SUSHELL} @ ${DEBUGTTY}
+        bash completions dir:              ${with_bashcompletiondir}
+        zsh completions dir:               ${with_zshcompletiondir}
+        extra start script:                ${RC_LOCAL_SCRIPT_PATH_START}
+        extra stop script:                 ${RC_LOCAL_SCRIPT_PATH_STOP}
+        adm group:                         ${have_adm_group}
+        wheel group:                       ${have_wheel_group}
+        debug shell:                       ${SUSHELL} @ ${DEBUGTTY}
         TTY GID:                           ${TTY_GID}
-        Maximum system UID:                ${SYSTEM_UID_MAX}
-        Maximum system GID:                ${SYSTEM_GID_MAX}
-        Certificate root:                  ${CERTIFICATEROOT}
-        Support URL:                       ${SUPPORT_URL}
+        maximum system UID:                ${SYSTEM_UID_MAX}
+        maximum system GID:                ${SYSTEM_GID_MAX}
+        certificate root:                  ${CERTIFICATEROOT}
+        support URL:                       ${SUPPORT_URL}
         nobody user name:                  ${NOBODY_USER_NAME}
         nobody group name:                 ${NOBODY_GROUP_NAME}
-        Fallback hostname:                 ${FALLBACK_HOSTNAME}
+        fallback hostname:                 ${FALLBACK_HOSTNAME}
 
         CFLAGS:   ${OUR_CFLAGS} ${CFLAGS}
         CPPFLAGS: ${OUR_CPPFLAGS} ${CPPFLAGS}
index cfdfef567a2489b7dfbc8385b70854316ab6952c..65c87aeac71c36c8c2374e32521cdf0aa9433137 100644 (file)
 evdev:name:*DualPoint Stick:dmi:bvn*:bvr*:bd*:svnDellInc.:pnLatitudeD620*:pvr*
  POINTINGSTICK_CONST_ACCEL=0.5
 
+# Latitude E5570
+evdev:name:*DualPoint Stick:dmi:bvn*:bvr*:bd*:svnDellInc.:pnLatitudeE5570*:pvr*
+ POINTINGSTICK_CONST_ACCEL=0.1
+
 # Latitude E6320
 evdev:name:*DualPoint Stick:dmi:bvn*:bvr*:bd*:svnDellInc.:pnLatitudeE6320*:pvr*
  POINTINGSTICK_CONST_ACCEL=2.0
index 72a244d2eb0cb40351ca76824bbf3e0bffb53199..5204db40730117772f74ba0216fe91c87c68b9c7 100644 (file)
         all known core dumps.</para></listitem>
       </varlistentry>
 
+      <varlistentry>
+        <term><option>-S</option></term>
+        <term><option>--since</option></term>
+
+        <listitem><para>Only print entries which are since the specified date.</para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><option>-U</option></term>
+        <term><option>--until</option></term>
+
+        <listitem><para>Only print entries which are until the specified date.</para></listitem>
+      </varlistentry>
+
       <varlistentry>
         <term><option>-r</option></term>
         <term><option>--reverse</option></term>
index 75bbc10215954b4aca26ed890647e7b8a5d0561c..cae5312db25e2876ee488c93eb359411eb53826c 100644 (file)
         a new 128-bit ID suitable for identifying messages. This is
         intended for usage by developers who need a new identifier for
         a new message they introduce and want to make
-        recognizable. This will print the new ID in three different
+        recognizable. This will print the new ID in four different
         formats which can be copied into source code or similar.
         </para></listitem>
       </varlistentry>
index 415b8d3cf9872e947bc894cc24e776d3980e83d9..f02ca3e7bc999138ff933995c22dff5385adf39d 100644 (file)
       <varlistentry>
         <term><varname>systemd.unit=</varname></term>
         <term><varname>rd.systemd.unit=</varname></term>
-        <term><varname>systemd.dump_core=</varname></term>
-        <term><varname>systemd.crash_chvt=</varname></term>
-        <term><varname>systemd.crash_shell=</varname></term>
-        <term><varname>systemd.crash_reboot=</varname></term>
-        <term><varname>systemd.confirm_spawn=</varname></term>
-        <term><varname>systemd.show_status=</varname></term>
+        <term><varname>systemd.dump_core</varname></term>
+        <term><varname>systemd.crash_chvt</varname></term>
+        <term><varname>systemd.crash_shell</varname></term>
+        <term><varname>systemd.crash_reboot</varname></term>
+        <term><varname>systemd.confirm_spawn</varname></term>
+        <term><varname>systemd.show_status</varname></term>
         <term><varname>systemd.log_target=</varname></term>
         <term><varname>systemd.log_level=</varname></term>
-        <term><varname>systemd.log_color=</varname></term>
         <term><varname>systemd.log_location=</varname></term>
+        <term><varname>systemd.log_color</varname></term>
         <term><varname>systemd.default_standard_output=</varname></term>
         <term><varname>systemd.default_standard_error=</varname></term>
         <term><varname>systemd.setenv=</varname></term>
         <term><varname>systemd.machine_id=</varname></term>
+        <term><varname>systemd.unified_cgroup_hierarchy</varname></term>
+        <term><varname>systemd.legacy_systemd_cgroup_controller</varname></term>
         <listitem>
           <para>Parameters understood by the system and service
           manager to control system behavior. For details, see
index edeced56b58148d1e3a0519b04cf8746c5584909..5d4986b6bfb508900881b734487be50b1245d2de 100644 (file)
         <filename>/proc/sys</filename>, <filename>/sys</filename>, <filename>/proc/sysrq-trigger</filename>,
         <filename>/proc/latency_stats</filename>, <filename>/proc/acpi</filename>,
         <filename>/proc/timer_stats</filename>, <filename>/proc/fs</filename> and <filename>/proc/irq</filename> will
-        be made read-only to all processes of the unit. Usually, tunable kernel variables should only be written at
-        boot-time, with the <citerefentry><refentrytitle>sysctl.d</refentrytitle><manvolnum>5</manvolnum></citerefentry>
-        mechanism. Almost no services need to write to these at runtime; it is hence recommended to turn this on for
-        most services. For this setting the same restrictions regarding mount propagation and privileges apply as for
-        <varname>ReadOnlyPaths=</varname> and related calls, see above. Defaults to off.
-        If turned on and if running in user mode, or in system mode, but without the <constant>CAP_SYS_ADMIN</constant>
-        capability (e.g. setting <varname>User=</varname>), <varname>NoNewPrivileges=yes</varname>
-        is implied. Note that this option does not prevent kernel tuning through IPC interfaces
-        and external programs. However <varname>InaccessiblePaths=</varname> can be used to
-        make some IPC file system objects inaccessible.</para></listitem>
+        be made read-only to all processes of the unit. Usually, tunable kernel variables should be initialized only at
+        boot-time, for example with the
+        <citerefentry><refentrytitle>sysctl.d</refentrytitle><manvolnum>5</manvolnum></citerefentry> mechanism. Few
+        services need to write to these at runtime; it is hence recommended to turn this on for most services. For this
+        setting the same restrictions regarding mount propagation and privileges apply as for
+        <varname>ReadOnlyPaths=</varname> and related calls, see above. Defaults to off.  If turned on and if running
+        in user mode, or in system mode, but without the <constant>CAP_SYS_ADMIN</constant> capability (e.g.  services
+        for which <varname>User=</varname> is set), <varname>NoNewPrivileges=yes</varname> is implied. Note that this
+        option does not prevent indirect changes to kernel tunables effected by IPC calls to other processes. However,
+        <varname>InaccessiblePaths=</varname> may be used to make relevant IPC file system objects inaccessible. If
+        <varname>ProtectKernelTunables=</varname> is set, <varname>MountAPIVFS=yes</varname> is
+        implied.</para></listitem>
       </varlistentry>
 
       <varlistentry>
         unit. Except for container managers no services should require write access to the control groups hierarchies;
         it is hence recommended to turn this on for most services. For this setting the same restrictions regarding
         mount propagation and privileges apply as for <varname>ReadOnlyPaths=</varname> and related calls, see
-        above. Defaults to off.</para></listitem>
+        above. Defaults to off. If <varname>ProtectControlGroups=</varname> is set, <varname>MountAPIVFS=yes</varname> is
+        implied.</para></listitem>
       </varlistentry>
 
       <varlistentry>
index bfcc0c13b0c791633da1c32d4222dba934a894ed..4856dea824b55eff4862087c9ecb359a73a9f21c 100644 (file)
 
   <refsynopsisdiv>
     <cmdsynopsis>
-      <command>systemd <arg choice="opt" rep="repeat">OPTIONS</arg></command>
+      <command>systemd</command>
+      <arg choice="opt" rep="repeat">OPTIONS</arg>
     </cmdsynopsis>
     <cmdsynopsis>
-      <command>init <arg choice="opt" rep="repeat">OPTIONS</arg> <arg choice="req">COMMAND</arg></command>
+      <command>init</command>
+      <arg choice="opt" rep="repeat">OPTIONS</arg>
+      <arg choice="req">COMMAND</arg>
     </cmdsynopsis>
   </refsynopsisdiv>
 
         user instance. This setting may also be enabled during boot,
         on the kernel command line via the
         <varname>systemd.crash_vt=</varname> option, see
+        <!-- FIXME: there is no crash_vt command line option? -->
         below.</para></listitem>
       </varlistentry>
 
       </varlistentry>
 
       <varlistentry>
-        <term><varname>systemd.dump_core=</varname></term>
+        <term><varname>systemd.dump_core</varname></term>
 
-        <listitem><para>Takes a boolean argument. If
-        <option>yes</option>, the systemd manager (PID 1) dumps core
-        when it crashes.  Otherwise, no core dump is created. Defaults
-        to <option>yes</option>.</para></listitem>
+        <listitem><para>Takes a boolean argument or enables the option if specified
+        without an argument. If enabled, the systemd manager (PID 1) dumps core when
+        it crashes. Otherwise, no core dump is created. Defaults to enabled.</para>
+        </listitem>
       </varlistentry>
 
       <varlistentry>
-        <term><varname>systemd.crash_chvt=</varname></term>
+        <term><varname>systemd.crash_chvt</varname></term>
 
-        <listitem><para>Takes a positive integer, or a boolean
-        argument. If a positive integer (in the range 1โ€“63) is
-        specified, the system manager (PID 1) will activate the specified
-        virtual terminal (VT) when it crashes. Defaults to
-        <constant>no</constant>, meaning that no such switch is
-        attempted. If set to <constant>yes</constant>, the VT the
-        kernel messages are written to is selected.</para></listitem>
+        <listitem><para>Takes a positive integer, or a boolean argument. Can be also
+        specified without an argument, with the same effect as a positive boolean. If
+        a positive integer (in the range 1โ€“63) is specified, the system manager (PID
+        1) will activate the specified virtual terminal (VT) when it
+        crashes. Defaults to disabled, meaning that no such switch is attempted. If
+        set to enabled, the VT the kernel messages are written to is selected.
+        </para></listitem>
       </varlistentry>
 
       <varlistentry>
-        <term><varname>systemd.crash_shell=</varname></term>
+        <term><varname>systemd.crash_shell</varname></term>
 
-        <listitem><para>Takes a boolean argument. If
-        <option>yes</option>, the system manager (PID 1) spawns a
-        shell when it crashes, after a 10s delay. Otherwise, no shell
-        is spawned. Defaults to <option>no</option>, for security
-        reasons, as the shell is not protected by password
+        <listitem><para>Takes a boolean argument or enables the option if specified
+        without an argument. If enabled, the system manager (PID 1) spawns a shell
+        when it crashes, after a 10s delay. Otherwise, no shell is spawned. Defaults
+        to disabled, for security reasons, as the shell is not protected by password
         authentication.</para></listitem>
       </varlistentry>
 
       <varlistentry>
-        <term><varname>systemd.crash_reboot=</varname></term>
+        <term><varname>systemd.crash_reboot</varname></term>
 
-        <listitem><para>Takes a boolean argument. If
-        <option>yes</option>, the system manager (PID 1) will reboot
-        the machine automatically when it crashes, after a 10s delay.
-        Otherwise, the system will hang indefinitely. Defaults to
-        <option>no</option>, in order to avoid a reboot loop. If
-        combined with <varname>systemd.crash_shell=</varname>, the
+        <listitem><para>Takes a boolean argument or enables the option if specified
+        without an argument. If enabled, the system manager (PID 1) will reboot the
+        machine automatically when it crashes, after a 10s delay.  Otherwise, the
+        system will hang indefinitely. Defaults to disabled, in order to avoid a
+        reboot loop. If combined with <varname>systemd.crash_shell</varname>, the
         system is rebooted after the shell exits.</para></listitem>
       </varlistentry>
 
       <varlistentry>
-        <term><varname>systemd.confirm_spawn=</varname></term>
+        <term><varname>systemd.confirm_spawn</varname></term>
 
-        <listitem><para>Takes a boolean argument or a path to the
-        virtual console where the confirmation messages should be
-        emitted. If <option>yes</option>, the system manager (PID 1)
-        asks for confirmation when spawning processes using
-        <option>/dev/console</option>. If a path or a console name
-        (such as <literal>ttyS0</literal>) is provided, the virtual
-        console pointed to by this path or described by the give name
-        will be used instead. Defaults to <option>no</option>.</para></listitem>
+        <listitem><para>Takes a boolean argument or a path to the virtual console
+        where the confirmation messages should be emitted. Can be also specified
+        without an argument, with the same effect as a positive boolean. If enabled,
+        the system manager (PID 1) asks for confirmation when spawning processes
+        using <option>/dev/console</option>. If a path or a console name (such as
+        <literal>ttyS0</literal>) is provided, the virtual console pointed to by this
+        path or described by the give name will be used instead. Defaults to disabled.
+        </para></listitem>
       </varlistentry>
 
       <varlistentry>
-        <term><varname>systemd.show_status=</varname></term>
+        <term><varname>systemd.show_status</varname></term>
 
-        <listitem><para>Takes a boolean argument or the constant <constant>auto</constant>. If <option>yes</option>,
-        the systemd manager (PID 1) shows terse service status updates on the console during bootup.
-        <constant>auto</constant> behaves like <option>false</option> until a unit fails or there is a significant
-        delay in boot.  Defaults to <option>yes</option>, unless <option>quiet</option> is passed as kernel command
-        line option, in which case it defaults to <constant>auto</constant>. If specified overrides the system manager
-        configuration file option <option>ShowStatus=</option>, see
-        <citerefentry><refentrytitle>systemd-system.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>. However,
-        the process command line option <option>--show-status=</option> takes precedence over both this kernel command
-        line option and the configuration file option.</para></listitem>
+        <listitem><para>Takes a boolean argument or the constant
+        <constant>auto</constant>. Can be also specified without an argument, with
+        the same effect as a positive boolean.  If enabled, the systemd manager (PID
+        1) shows terse service status updates on the console during bootup.
+        <constant>auto</constant> behaves like <option>false</option> until a unit
+        fails or there is a significant delay in boot. Defaults to enabled, unless
+        <option>quiet</option> is passed as kernel command line option, in which case
+        it defaults to <constant>auto</constant>. If specified overrides the system
+        manager configuration file option <option>ShowStatus=</option>, see
+        <citerefentry><refentrytitle>systemd-system.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>.
+        However, the process command line option <option>--show-status=</option>
+        takes precedence over both this kernel command line option and the
+        configuration file option.</para></listitem>
       </varlistentry>
 
       <varlistentry>
         <term><varname>systemd.log_target=</varname></term>
         <term><varname>systemd.log_level=</varname></term>
-        <term><varname>systemd.log_color=</varname></term>
         <term><varname>systemd.log_location=</varname></term>
+        <term><varname>systemd.log_color</varname></term>
 
-        <listitem><para>Controls log output, with the same effect as
-        the <varname>$SYSTEMD_LOG_TARGET</varname>,
+        <listitem><para>Controls log output, with the same effect as the
+        <varname>$SYSTEMD_LOG_TARGET</varname>,
         <varname>$SYSTEMD_LOG_LEVEL</varname>,
-        <varname>$SYSTEMD_LOG_COLOR</varname>,
-        <varname>$SYSTEMD_LOG_LOCATION</varname> environment variables
-        described above.</para></listitem>
+        <varname>$SYSTEMD_LOG_LOCATION</varname>,
+        <varname>$SYSTEMD_LOG_COLOR</varname> environment variables described above.
+        <varname>systemd.log_color</varname> can be specified without an argument,
+        with the same effect as a positive boolean.</para></listitem>
       </varlistentry>
 
       <varlistentry>
         for every boot.</para></listitem>
       </varlistentry>
 
+      <varlistentry>
+        <term><varname>systemd.unified_cgroup_hierarchy</varname></term>
+
+        <listitem><para>When specified without an argument or with a true argument,
+        enables the usage of
+        <ulink url="https://www.kernel.org/doc/Documentation/cgroup-v2.txt">unified cgroup hierarchy</ulink>
+        (a.k.a.ย cgroups-v2). When specified with a false argument, fall back to
+        hybrid or full legacy cgroup hierarchy.</para>
+
+        <para>If this option is not specified, the default behaviour is determined
+        during compilation (the <option>--with-default-hierarchy=</option>
+        option). If the kernel does not support unified cgroup hierarchy, the legacy
+        hierarchy will be used even if this option is specified.</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><varname>systemd.legacy_systemd_cgroup_controller</varname></term>
+
+        <listitem><para>Takes effect if the full unified cgroup hierarchy is not used
+        (see previous option). When specified without an argument or with a true
+        argument, disables the use of "hybrid" cgroup hierarchy (i.e. a cgroups-v2
+        tree used for systemd, and
+        <ulink url="https://www.kernel.org/doc/Documentation/cgroup-v1/">legacy
+        cgroup hierarchy</ulink>, a.k.a.ย cgroups-v1, for other controllers), and
+        forces a full "legacy" mode. When specified with a false argument, enables
+        the use of "hybrid" hierarchy.</para>
+
+        <para>If this option is not specified, the default behaviour is determined
+        during compilation (the <option>--with-default-hierarchy=</option>
+        option). If the kernel does not support unified cgroup hierarchy, the legacy
+        hierarchy will be used  even if this option is specified.</para>
+        </listitem>
+      </varlistentry>
+
       <varlistentry>
         <term><varname>quiet</varname></term>
 
index d34f89e2bb9cc3f56891c75f338578da46000926..87fe473e091905db48a032a269eed1af0fbdaf6f 100644 (file)
@@ -38,7 +38,7 @@ _coredumpctl() {
         local i verb comps
         local cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]}
         local OPTS='-h --help --version --no-pager --no-legend -o --output -F --field -1
-                    -r --reverse'
+                    -r --reverse -S --since -U --until'
 
         local -A VERBS=(
             [LIST]='list'
index 64b44c1214cd40263881644dd04a21a9295c41d6..e469bca9582b25d4182a1175ca86e2092085cac0 100644 (file)
@@ -32,6 +32,8 @@ _arguments \
     {-o+,--output=}'[Write output to FILE]:output file:_files' \
     {-F+,--field=}'[Show field in list output]:field' \
     '-1[Show information about most recent entry only]' \
+    {-S,--since}'[Print entries since the specified date]' \
+    {-U,--until}'[Print entries until the specified date]' \
     {-r,--reverse}'[Show the newest entries first]' \
     '--no-pager[Do not pipe output into a pager]' \
     '--no-legend[Do not print the column headers]' \
index 633c2aaccb58bcdb72ab162733da18b60a77ba4c..91312bd2a3cb89692b781314b6799f22253c3134 100644 (file)
 #define _IDN_FEATURE_ "-IDN"
 #endif
 
+#define _CGROUP_HIEARCHY_ "default-hierarchy=" DEFAULT_HIERARCHY_NAME
+
 #define SYSTEMD_FEATURES                                                \
         _PAM_FEATURE_ " "                                               \
         _AUDIT_FEATURE_ " "                                             \
         _BLKID_FEATURE_ " "                                             \
         _ELFUTILS_FEATURE_ " "                                          \
         _KMOD_FEATURE_ " "                                              \
-        _IDN_FEATURE_
+        _IDN_FEATURE_ " "                                               \
+        _CGROUP_HIEARCHY_
index 6948ed393132cc701a3bb35ce58d08e1fd9a46b6..bda5c555ad38fe6e2e069e4b23670a7508c29753 100644 (file)
@@ -208,6 +208,18 @@ int cg_rmdir(const char *controller, const char *path) {
         if (r < 0 && errno != ENOENT)
                 return -errno;
 
+        r = cg_hybrid_unified();
+        if (r < 0)
+                return r;
+        if (r == 0)
+                return 0;
+
+        if (streq(controller, SYSTEMD_CGROUP_CONTROLLER)) {
+                r = cg_rmdir(SYSTEMD_CGROUP_CONTROLLER_LEGACY, path);
+                if (r < 0)
+                        log_warning_errno(r, "Failed to remove compat systemd cgroup %s: %m", path);
+        }
+
         return 0;
 }
 
@@ -542,6 +554,13 @@ static const char *controller_to_dirname(const char *controller) {
          * just cuts off the name= prefixed used for named
          * hierarchies, if it is specified. */
 
+        if (streq(controller, SYSTEMD_CGROUP_CONTROLLER)) {
+                if (cg_hybrid_unified() > 0)
+                        controller = SYSTEMD_CGROUP_CONTROLLER_HYBRID;
+                else
+                        controller = SYSTEMD_CGROUP_CONTROLLER_LEGACY;
+        }
+
         e = startswith(controller, "name=");
         if (e)
                 return e;
@@ -594,7 +613,7 @@ static int join_path_unified(const char *path, const char *suffix, char **fs) {
 }
 
 int cg_get_path(const char *controller, const char *path, const char *suffix, char **fs) {
-        int unified, r;
+        int r;
 
         assert(fs);
 
@@ -623,11 +642,10 @@ int cg_get_path(const char *controller, const char *path, const char *suffix, ch
         if (!cg_controller_is_valid(controller))
                 return -EINVAL;
 
-        unified = cg_all_unified();
-        if (unified < 0)
-                return unified;
-
-        if (unified > 0)
+        r = cg_all_unified();
+        if (r < 0)
+                return r;
+        if (r > 0)
                 r = join_path_unified(path, suffix, fs);
         else
                 r = join_path_legacy(controller, path, suffix, fs);
@@ -639,7 +657,7 @@ int cg_get_path(const char *controller, const char *path, const char *suffix, ch
 }
 
 static int controller_is_accessible(const char *controller) {
-        int unified;
+        int r;
 
         assert(controller);
 
@@ -651,10 +669,10 @@ static int controller_is_accessible(const char *controller) {
         if (!cg_controller_is_valid(controller))
                 return -EINVAL;
 
-        unified = cg_all_unified();
-        if (unified < 0)
-                return unified;
-        if (unified > 0) {
+        r = cg_all_unified();
+        if (r < 0)
+                return r;
+        if (r > 0) {
                 /* We don't support named hierarchies if we are using
                  * the unified hierarchy. */
 
@@ -708,7 +726,7 @@ static int trim_cb(const char *path, const struct stat *sb, int typeflag, struct
 
 int cg_trim(const char *controller, const char *path, bool delete_root) {
         _cleanup_free_ char *fs = NULL;
-        int r = 0;
+        int r = 0, q;
 
         assert(path);
 
@@ -731,6 +749,15 @@ int cg_trim(const char *controller, const char *path, bool delete_root) {
                         return -errno;
         }
 
+        q = cg_hybrid_unified();
+        if (q < 0)
+                return q;
+        if (q > 0 && streq(controller, SYSTEMD_CGROUP_CONTROLLER)) {
+                q = cg_trim(SYSTEMD_CGROUP_CONTROLLER_LEGACY, path, delete_root);
+                if (q < 0)
+                        log_warning_errno(q, "Failed to trim compat systemd cgroup %s: %m", path);
+        }
+
         return r;
 }
 
@@ -754,6 +781,16 @@ int cg_create(const char *controller, const char *path) {
                 return -errno;
         }
 
+        r = cg_hybrid_unified();
+        if (r < 0)
+                return r;
+
+        if (r > 0 && streq(controller, SYSTEMD_CGROUP_CONTROLLER)) {
+                r = cg_create(SYSTEMD_CGROUP_CONTROLLER_LEGACY, path);
+                if (r < 0)
+                        log_warning_errno(r, "Failed to create compat systemd cgroup %s: %m", path);
+        }
+
         return 1;
 }
 
@@ -791,7 +828,21 @@ int cg_attach(const char *controller, const char *path, pid_t pid) {
 
         xsprintf(c, PID_FMT "\n", pid);
 
-        return write_string_file(fs, c, 0);
+        r = write_string_file(fs, c, 0);
+        if (r < 0)
+                return r;
+
+        r = cg_hybrid_unified();
+        if (r < 0)
+                return r;
+
+        if (r > 0 && streq(controller, SYSTEMD_CGROUP_CONTROLLER)) {
+                r = cg_attach(SYSTEMD_CGROUP_CONTROLLER_LEGACY, path, pid);
+                if (r < 0)
+                        log_warning_errno(r, "Failed to attach %d to compat systemd cgroup %s: %m", pid, path);
+        }
+
+        return 0;
 }
 
 int cg_attach_fallback(const char *controller, const char *path, pid_t pid) {
@@ -840,7 +891,20 @@ int cg_set_group_access(
         if (r < 0)
                 return r;
 
-        return chmod_and_chown(fs, mode, uid, gid);
+        r = chmod_and_chown(fs, mode, uid, gid);
+        if (r < 0)
+                return r;
+
+        r = cg_hybrid_unified();
+        if (r < 0)
+                return r;
+        if (r > 0 && streq(controller, SYSTEMD_CGROUP_CONTROLLER)) {
+                r = cg_set_group_access(SYSTEMD_CGROUP_CONTROLLER_LEGACY, path, mode, uid, gid);
+                if (r < 0)
+                        log_warning_errno(r, "Failed to set group access on compat systemd cgroup %s: %m", path);
+        }
+
+        return 0;
 }
 
 int cg_set_task_access(
@@ -851,7 +915,7 @@ int cg_set_task_access(
                 gid_t gid) {
 
         _cleanup_free_ char *fs = NULL, *procs = NULL;
-        int r, unified;
+        int r;
 
         assert(path);
 
@@ -869,16 +933,24 @@ int cg_set_task_access(
         if (r < 0)
                 return r;
 
-        unified = cg_unified(controller);
-        if (unified < 0)
-                return unified;
-        if (unified)
-                return 0;
+        r = cg_unified_controller(controller);
+        if (r < 0)
+                return r;
+        if (r == 0) {
+                /* Compatibility, Always keep values for "tasks" in sync with
+                 * "cgroup.procs" */
+                if (cg_get_path(controller, path, "tasks", &procs) >= 0)
+                        (void) chmod_and_chown(procs, mode, uid, gid);
+        }
 
-        /* Compatibility, Always keep values for "tasks" in sync with
-         * "cgroup.procs" */
-        if (cg_get_path(controller, path, "tasks", &procs) >= 0)
-                (void) chmod_and_chown(procs, mode, uid, gid);
+        r = cg_hybrid_unified();
+        if (r < 0)
+                return r;
+        if (r > 0 && streq(controller, SYSTEMD_CGROUP_CONTROLLER)) {
+                r = cg_set_task_access(SYSTEMD_CGROUP_CONTROLLER_LEGACY, path, mode, uid, gid);
+                if (r < 0)
+                        log_warning_errno(r, "Failed to set task access on compat systemd cgroup %s: %m", path);
+        }
 
         return 0;
 }
@@ -923,7 +995,7 @@ int cg_get_xattr(const char *controller, const char *path, const char *name, voi
 int cg_pid_get_path(const char *controller, pid_t pid, char **path) {
         _cleanup_fclose_ FILE *f = NULL;
         char line[LINE_MAX];
-        const char *fs;
+        const char *fs, *controller_str;
         size_t cs = 0;
         int unified;
 
@@ -936,11 +1008,17 @@ int cg_pid_get_path(const char *controller, pid_t pid, char **path) {
         } else
                 controller = SYSTEMD_CGROUP_CONTROLLER;
 
-        unified = cg_unified(controller);
+        unified = cg_unified_controller(controller);
         if (unified < 0)
                 return unified;
-        if (unified == 0)
-                cs = strlen(controller);
+        if (unified == 0) {
+                if (streq(controller, SYSTEMD_CGROUP_CONTROLLER))
+                        controller_str = SYSTEMD_CGROUP_CONTROLLER_LEGACY;
+                else
+                        controller_str = controller;
+
+                cs = strlen(controller_str);
+        }
 
         fs = procfs_file_alloca(pid, "cgroup");
         f = fopen(fs, "re");
@@ -977,7 +1055,7 @@ int cg_pid_get_path(const char *controller, pid_t pid, char **path) {
 
                         *e = 0;
                         FOREACH_WORD_SEPARATOR(word, k, l, ",", state) {
-                                if (k == cs && memcmp(word, controller, cs) == 0) {
+                                if (k == cs && memcmp(word, controller_str, cs) == 0) {
                                         found = true;
                                         break;
                                 }
@@ -1001,14 +1079,14 @@ int cg_pid_get_path(const char *controller, pid_t pid, char **path) {
 int cg_install_release_agent(const char *controller, const char *agent) {
         _cleanup_free_ char *fs = NULL, *contents = NULL;
         const char *sc;
-        int r, unified;
+        int r;
 
         assert(agent);
 
-        unified = cg_unified(controller);
-        if (unified < 0)
-                return unified;
-        if (unified) /* doesn't apply to unified hierarchy */
+        r = cg_unified_controller(controller);
+        if (r < 0)
+                return r;
+        if (r > 0) /* doesn't apply to unified hierarchy */
                 return -EOPNOTSUPP;
 
         r = cg_get_path(controller, NULL, "release_agent", &fs);
@@ -1054,12 +1132,12 @@ int cg_install_release_agent(const char *controller, const char *agent) {
 
 int cg_uninstall_release_agent(const char *controller) {
         _cleanup_free_ char *fs = NULL;
-        int r, unified;
+        int r;
 
-        unified = cg_unified(controller);
-        if (unified < 0)
-                return unified;
-        if (unified) /* Doesn't apply to unified hierarchy */
+        r = cg_unified_controller(controller);
+        if (r < 0)
+                return r;
+        if (r > 0) /* Doesn't apply to unified hierarchy */
                 return -EOPNOTSUPP;
 
         r = cg_get_path(controller, NULL, "notify_on_release", &fs);
@@ -1104,7 +1182,7 @@ int cg_is_empty(const char *controller, const char *path) {
 }
 
 int cg_is_empty_recursive(const char *controller, const char *path) {
-        int unified, r;
+        int r;
 
         assert(path);
 
@@ -1112,11 +1190,10 @@ int cg_is_empty_recursive(const char *controller, const char *path) {
         if (controller && (isempty(path) || path_equal(path, "/")))
                 return false;
 
-        unified = cg_unified(controller);
-        if (unified < 0)
-                return unified;
-
-        if (unified > 0) {
+        r = cg_unified_controller(controller);
+        if (r < 0)
+                return r;
+        if (r > 0) {
                 _cleanup_free_ char *t = NULL;
 
                 /* On the unified hierarchy we can check empty state
@@ -1833,6 +1910,9 @@ bool cg_controller_is_valid(const char *p) {
         if (!p)
                 return false;
 
+        if (streq(p, SYSTEMD_CGROUP_CONTROLLER))
+                return true;
+
         s = startswith(p, "name=");
         if (s)
                 p = s;
@@ -1986,7 +2066,7 @@ int cg_get_keyed_attribute(const char *controller, const char *path, const char
 
 int cg_create_everywhere(CGroupMask supported, CGroupMask mask, const char *path) {
         CGroupController c;
-        int r, unified;
+        int r;
 
         /* This one will create a cgroup in our private tree, but also
          * duplicate it in the trees specified in mask, and remove it
@@ -1998,10 +2078,10 @@ int cg_create_everywhere(CGroupMask supported, CGroupMask mask, const char *path
                 return r;
 
         /* If we are in the unified hierarchy, we are done now */
-        unified = cg_all_unified();
-        if (unified < 0)
-                return unified;
-        if (unified > 0)
+        r = cg_all_unified();
+        if (r < 0)
+                return r;
+        if (r > 0)
                 return 0;
 
         /* Otherwise, do the same in the other hierarchies */
@@ -2022,16 +2102,16 @@ int cg_create_everywhere(CGroupMask supported, CGroupMask mask, const char *path
 
 int cg_attach_everywhere(CGroupMask supported, const char *path, pid_t pid, cg_migrate_callback_t path_callback, void *userdata) {
         CGroupController c;
-        int r, unified;
+        int r;
 
         r = cg_attach(SYSTEMD_CGROUP_CONTROLLER, path, pid);
         if (r < 0)
                 return r;
 
-        unified = cg_all_unified();
-        if (unified < 0)
-                return unified;
-        if (unified > 0)
+        r = cg_all_unified();
+        if (r < 0)
+                return r;
+        if (r > 0)
                 return 0;
 
         for (c = 0; c < _CGROUP_CONTROLLER_MAX; c++) {
@@ -2072,7 +2152,7 @@ int cg_attach_many_everywhere(CGroupMask supported, const char *path, Set* pids,
 
 int cg_migrate_everywhere(CGroupMask supported, const char *from, const char *to, cg_migrate_callback_t to_callback, void *userdata) {
         CGroupController c;
-        int r = 0, unified;
+        int r = 0, q;
 
         if (!path_equal(from, to))  {
                 r = cg_migrate_recursive(SYSTEMD_CGROUP_CONTROLLER, from, SYSTEMD_CGROUP_CONTROLLER, to, CGROUP_REMOVE);
@@ -2080,10 +2160,10 @@ int cg_migrate_everywhere(CGroupMask supported, const char *from, const char *to
                         return r;
         }
 
-        unified = cg_all_unified();
-        if (unified < 0)
-                return unified;
-        if (unified > 0)
+        q = cg_all_unified();
+        if (q < 0)
+                return q;
+        if (q > 0)
                 return r;
 
         for (c = 0; c < _CGROUP_CONTROLLER_MAX; c++) {
@@ -2107,16 +2187,16 @@ int cg_migrate_everywhere(CGroupMask supported, const char *from, const char *to
 
 int cg_trim_everywhere(CGroupMask supported, const char *path, bool delete_root) {
         CGroupController c;
-        int r, unified;
+        int r, q;
 
         r = cg_trim(SYSTEMD_CGROUP_CONTROLLER, path, delete_root);
         if (r < 0)
                 return r;
 
-        unified = cg_all_unified();
-        if (unified < 0)
-                return unified;
-        if (unified > 0)
+        q = cg_all_unified();
+        if (q < 0)
+                return q;
+        if (q > 0)
                 return r;
 
         for (c = 0; c < _CGROUP_CONTROLLER_MAX; c++) {
@@ -2133,16 +2213,16 @@ int cg_trim_everywhere(CGroupMask supported, const char *path, bool delete_root)
 
 int cg_mask_supported(CGroupMask *ret) {
         CGroupMask mask = 0;
-        int r, unified;
+        int r;
 
         /* Determines the mask of supported cgroup controllers. Only
          * includes controllers we can make sense of and that are
          * actually accessible. */
 
-        unified = cg_all_unified();
-        if (unified < 0)
-                return unified;
-        if (unified > 0) {
+        r = cg_all_unified();
+        if (r < 0)
+                return r;
+        if (r > 0) {
                 _cleanup_free_ char *root = NULL, *controllers = NULL, *path = NULL;
                 const char *c;
 
@@ -2262,7 +2342,18 @@ int cg_kernel_controllers(Set *controllers) {
 
 static thread_local CGroupUnified unified_cache = CGROUP_UNIFIED_UNKNOWN;
 
-static int cg_update_unified(void) {
+/* The hybrid mode was initially implemented in v232 and simply mounted cgroup v2 on /sys/fs/cgroup/systemd.  This
+ * unfortunately broke other tools (such as docker) which expected the v1 "name=systemd" hierarchy on
+ * /sys/fs/cgroup/systemd.  From v233 and on, the hybrid mode mountnbs v2 on /sys/fs/cgroup/unified and maintains
+ * "name=systemd" hierarchy on /sys/fs/cgroup/systemd for compatibility with other tools.
+ *
+ * To keep live upgrade working, we detect and support v232 layout.  When v232 layout is detected, to keep cgroup v2
+ * process management but disable the compat dual layout, we return %true on
+ * cg_unified_controller(SYSTEMD_CGROUP_CONTROLLER) and %false on cg_hybrid_unified().
+ */
+static thread_local bool unified_systemd_v232;
+
+static int cg_unified_update(void) {
 
         struct statfs fs;
 
@@ -2280,54 +2371,83 @@ static int cg_update_unified(void) {
         if (F_TYPE_EQUAL(fs.f_type, CGROUP2_SUPER_MAGIC))
                 unified_cache = CGROUP_UNIFIED_ALL;
         else if (F_TYPE_EQUAL(fs.f_type, TMPFS_MAGIC)) {
-                if (statfs("/sys/fs/cgroup/systemd/", &fs) < 0)
-                        return -errno;
-
-                unified_cache = F_TYPE_EQUAL(fs.f_type, CGROUP2_SUPER_MAGIC) ?
-                        CGROUP_UNIFIED_SYSTEMD : CGROUP_UNIFIED_NONE;
+                if (statfs("/sys/fs/cgroup/unified/", &fs) == 0 &&
+                    F_TYPE_EQUAL(fs.f_type, CGROUP2_SUPER_MAGIC)) {
+                        unified_cache = CGROUP_UNIFIED_SYSTEMD;
+                        unified_systemd_v232 = false;
+                } else if (statfs("/sys/fs/cgroup/systemd/", &fs) == 0 &&
+                           F_TYPE_EQUAL(fs.f_type, CGROUP2_SUPER_MAGIC)) {
+                        unified_cache = CGROUP_UNIFIED_SYSTEMD;
+                        unified_systemd_v232 = true;
+                } else {
+                        if (statfs("/sys/fs/cgroup/systemd/", &fs) < 0)
+                                return -errno;
+                        if (!F_TYPE_EQUAL(fs.f_type, CGROUP_SUPER_MAGIC))
+                                return -ENOMEDIUM;
+                        unified_cache = CGROUP_UNIFIED_NONE;
+                }
         } else
                 return -ENOMEDIUM;
 
         return 0;
 }
 
-int cg_unified(const char *controller) {
-
+int cg_unified_controller(const char *controller) {
         int r;
 
-        r = cg_update_unified();
+        r = cg_unified_update();
         if (r < 0)
                 return r;
 
-        if (streq_ptr(controller, SYSTEMD_CGROUP_CONTROLLER))
-                return unified_cache >= CGROUP_UNIFIED_SYSTEMD;
-        else
-                return unified_cache >= CGROUP_UNIFIED_ALL;
+        if (unified_cache == CGROUP_UNIFIED_NONE)
+                return false;
+
+        if (unified_cache >= CGROUP_UNIFIED_ALL)
+                return true;
+
+        return streq_ptr(controller, SYSTEMD_CGROUP_CONTROLLER);
 }
 
 int cg_all_unified(void) {
+        int r;
+
+        r = cg_unified_update();
+        if (r < 0)
+                return r;
 
-        return cg_unified(NULL);
+        return unified_cache >= CGROUP_UNIFIED_ALL;
 }
 
-void cg_unified_flush(void) {
+int cg_hybrid_unified(void) {
+        int r;
+
+        r = cg_unified_update();
+        if (r < 0)
+                return r;
+
+        return unified_cache == CGROUP_UNIFIED_SYSTEMD && !unified_systemd_v232;
+}
+
+int cg_unified_flush(void) {
         unified_cache = CGROUP_UNIFIED_UNKNOWN;
+
+        return cg_unified_update();
 }
 
 int cg_enable_everywhere(CGroupMask supported, CGroupMask mask, const char *p) {
         _cleanup_free_ char *fs = NULL;
         CGroupController c;
-        int r, unified;
+        int r;
 
         assert(p);
 
         if (supported == 0)
                 return 0;
 
-        unified = cg_all_unified();
-        if (unified < 0)
-                return unified;
-        if (!unified) /* on the legacy hiearchy there's no joining of controllers defined */
+        r = cg_all_unified();
+        if (r < 0)
+                return r;
+        if (r == 0) /* on the legacy hiearchy there's no joining of controllers defined */
                 return 0;
 
         r = cg_get_path(SYSTEMD_CGROUP_CONTROLLER, p, "cgroup.subtree_control", &fs);
@@ -2359,63 +2479,69 @@ int cg_enable_everywhere(CGroupMask supported, CGroupMask mask, const char *p) {
 
 bool cg_is_unified_wanted(void) {
         static thread_local int wanted = -1;
-        int r, unified;
+        int r;
         bool b;
+        const bool is_default = DEFAULT_HIERARCHY == CGROUP_UNIFIED_ALL;
 
-        /* If the hierarchy is already mounted, then follow whatever
-         * was chosen for it. */
-        unified = cg_all_unified();
-        if (unified >= 0)
-                return unified;
-
-        /* Otherwise, let's see what the kernel command line has to
-         * say. Since checking that is expensive, let's cache the
-         * result. */
+        /* If we have a cached value, return that. */
         if (wanted >= 0)
                 return wanted;
 
+        /* If the hierarchy is already mounted, then follow whatever
+         * was chosen for it. */
+        if (cg_unified_flush() >= 0)
+                return (wanted = unified_cache >= CGROUP_UNIFIED_ALL);
+
+        /* Otherwise, let's see what the kernel command line has to say.
+         * Since checking is expensive, cache a non-error result. */
         r = proc_cmdline_get_bool("systemd.unified_cgroup_hierarchy", &b);
-        if (r < 0)
-                return false;
 
-        return (wanted = r > 0 ? b : false);
+        return (wanted = r > 0 ? b : is_default);
 }
 
 bool cg_is_legacy_wanted(void) {
-        return !cg_is_unified_wanted();
+        static thread_local int wanted = -1;
+
+        /* If we have a cached value, return that. */
+        if (wanted >= 0)
+                return wanted;
+
+        /* Check if we have cgroups2 already mounted. */
+        if (cg_unified_flush() >= 0 &&
+            unified_cache == CGROUP_UNIFIED_ALL)
+                return (wanted = false);
+
+        /* Otherwise, assume that at least partial legacy is wanted,
+         * since cgroups2 should already be mounted at this point. */
+        return (wanted = true);
 }
 
-bool cg_is_unified_systemd_controller_wanted(void) {
+bool cg_is_hybrid_wanted(void) {
         static thread_local int wanted = -1;
-        int r, unified;
+        int r;
         bool b;
+        const bool is_default = DEFAULT_HIERARCHY >= CGROUP_UNIFIED_SYSTEMD;
+        /* We default to true if the default is "hybrid", obviously,
+         * but also when the default is "unified", because if we get
+         * called, it means that unified hierarchy was not mounted. */
 
-        /* If the unified hierarchy is requested in full, no need to
-         * bother with this. */
-        if (cg_is_unified_wanted())
-                return 0;
+        /* If we have a cached value, return that. */
+        if (wanted >= 0)
+                return wanted;
 
         /* If the hierarchy is already mounted, then follow whatever
          * was chosen for it. */
-        unified = cg_unified(SYSTEMD_CGROUP_CONTROLLER);
-        if (unified >= 0)
-                return unified;
-
-        /* Otherwise, let's see what the kernel command line has to
-         * say. Since checking that is expensive, let's cache the
-         * result. */
-        if (wanted >= 0)
-                return wanted;
+        if (cg_unified_flush() >= 0 &&
+            unified_cache == CGROUP_UNIFIED_ALL)
+                return (wanted = false);
 
+        /* Otherwise, let's see what the kernel command line has to say.
+         * Since checking is expensive, cache a non-error result. */
         r = proc_cmdline_get_bool("systemd.legacy_systemd_cgroup_controller", &b);
-        if (r < 0)
-                return false;
-
-        return (wanted = r > 0 ? b : false);
-}
 
-bool cg_is_legacy_systemd_controller_wanted(void) {
-        return cg_is_legacy_wanted() && !cg_is_unified_systemd_controller_wanted();
+        /* The meaning of the kernel option is reversed wrt. to the return value
+         * of this function, hence the negation. */
+        return (wanted = r > 0 ? !b : is_default);
 }
 
 int cg_weight_parse(const char *s, uint64_t *ret) {
index 0aa27c4cd7cf181a095626389f8157b0156f455a..a522095d9574ccb6e0ef24f8862f87a305a16579 100644 (file)
@@ -241,13 +241,13 @@ int cg_kernel_controllers(Set *controllers);
 bool cg_ns_supported(void);
 
 int cg_all_unified(void);
-int cg_unified(const char *controller);
-void cg_unified_flush(void);
+int cg_hybrid_unified(void);
+int cg_unified_controller(const char *controller);
+int cg_unified_flush(void);
 
 bool cg_is_unified_wanted(void);
 bool cg_is_legacy_wanted(void);
-bool cg_is_unified_systemd_controller_wanted(void);
-bool cg_is_legacy_systemd_controller_wanted(void);
+bool cg_is_hybrid_wanted(void);
 
 const char* cgroup_controller_to_string(CGroupController c) _const_;
 CGroupController cgroup_controller_from_string(const char *s) _pure_;
index 6273ac9b4768c65aaf82dcc7314a490630531c51..e120b9eb4ef17bd810cf6d94b941a6051208835c 100644 (file)
@@ -558,7 +558,7 @@ int copy_file_atomic(const char *from, const char *to, mode_t mode, unsigned cha
         } else
                 r = rename_noreplace(AT_FDCWD, t, AT_FDCWD, to);
         if (r < 0) {
-                (void) unlink_noerrno(t);
+                (void) unlink(t);
                 return r;
         }
 
index 10d776ec8e5b34d5482c108de2d0ea5adfd312ca..200ea973c19041d4dbe2b9b33beb16b6a7c583b6 100644 (file)
@@ -36,7 +36,9 @@
 /* The default value for the net.unix.max_dgram_qlen sysctl */
 #define DEFAULT_UNIX_MAX_DGRAM_QLEN 512UL
 
-#define SYSTEMD_CGROUP_CONTROLLER "name=systemd"
+#define SYSTEMD_CGROUP_CONTROLLER_LEGACY "name=systemd"
+#define SYSTEMD_CGROUP_CONTROLLER_HYBRID "name=unified"
+#define SYSTEMD_CGROUP_CONTROLLER "_systemd"
 
 #define SIGNALS_CRASH_HANDLER SIGSEGV,SIGILL,SIGFPE,SIGBUS,SIGQUIT,SIGABRT
 #define SIGNALS_IGNORE SIGPIPE
index 2ca64c33019f8bb8930792b7ac0a9e67ce3bf999..1ec574e8a0e3d77a96bef77fb9cb2d29b2f4b974 100644 (file)
@@ -637,7 +637,7 @@ char *replace_env_n(const char *format, size_t n, char **env, unsigned flags) {
                                 break;
 
                         nest--;
-                        if (nest == 0) { // || !strchr(e+1, '}')) {
+                        if (nest == 0) {
                                 const char *t;
                                 _cleanup_free_ char *v = NULL;
 
index b9a9f748928058dbe30b99f06ad8346996c9791c..7c2c2b38f5112ce143387258de55bd15c4dd923a 100644 (file)
@@ -554,13 +554,14 @@ static int parse_env_file_internal(
                 }
         }
 
-        if (state == PRE_VALUE ||
-            state == VALUE ||
-            state == VALUE_ESCAPE ||
-            state == SINGLE_QUOTE_VALUE ||
-            state == SINGLE_QUOTE_VALUE_ESCAPE ||
-            state == DOUBLE_QUOTE_VALUE ||
-            state == DOUBLE_QUOTE_VALUE_ESCAPE) {
+        if (IN_SET(state,
+                   PRE_VALUE,
+                   VALUE,
+                   VALUE_ESCAPE,
+                   SINGLE_QUOTE_VALUE,
+                   SINGLE_QUOTE_VALUE_ESCAPE,
+                   DOUBLE_QUOTE_VALUE,
+                   DOUBLE_QUOTE_VALUE_ESCAPE)) {
 
                 key[n_key] = 0;
 
@@ -780,6 +781,7 @@ static int merge_env_file_push(
 
         if (!env_name_is_valid(key)) {
                 log_error("%s:%u: invalid variable name \"%s\", ignoring.", strna(filename), line, key);
+                free(value);
                 return 0;
         }
 
index 5fe5c71ff029cc953b669fd2e0d3ac427f14dd13..094acf179963ec1da3449fb7d5117fee67198e3e 100644 (file)
@@ -91,3 +91,9 @@ static inline void rmdir_and_free(char *p) {
         free(p);
 }
 DEFINE_TRIVIAL_CLEANUP_FUNC(char*, rmdir_and_free);
+
+static inline void unlink_and_free(char *p) {
+        (void) unlink(p);
+        free(p);
+}
+DEFINE_TRIVIAL_CLEANUP_FUNC(char*, unlink_and_free);
index f404a68236936ffb775b8ff71cc263a7c47f3bbb..410f3020e0474b9bda61af5c38a06a35919bc3b6 100644 (file)
@@ -28,7 +28,7 @@
 typedef struct khash khash;
 
 /* For plain hash functions. Hash functions commonly supported on today's kernels are: crc32c, crct10dif, crc32,
- * sha224, sha256, sha512, sha384, sha1, md5, md4, sha3-224, sha3-256, sha3-384, sha3-512, and more.*/
+ * sha224, sha256, sha512, sha384, sha1, md5, md4, sha3-224, sha3-256, sha3-384, sha3-512, and more. */
 int khash_new(khash **ret, const char *algorithm);
 
 /* For keyed hash functions. Hash functions commonly supported on today's kernels are: hmac(sha256), cmac(aes),
index e6d2d61d72b8946121a2a66324fe5709c2522775..36efc9ac7d8eaf598f776ba831c605d0f78f8070 100644 (file)
@@ -72,6 +72,7 @@ static bool show_color = false;
 static bool show_location = false;
 
 static bool upgrade_syslog_to_journal = false;
+static bool always_reopen_console = false;
 
 /* Akin to glibc's __abort_msg; which is private and we hence cannot
  * use here. */
@@ -95,7 +96,7 @@ static int log_open_console(void) {
         if (console_fd >= 0)
                 return 0;
 
-        if (getpid() == 1) {
+        if (always_reopen_console) {
                 console_fd = open_terminal("/dev/console", O_WRONLY|O_NOCTTY|O_CLOEXEC);
                 if (console_fd < 0)
                         return console_fd;
@@ -1171,3 +1172,7 @@ int log_syntax_internal(
                         unit_fmt, unit,
                         NULL);
 }
+
+void log_set_always_reopen_console(bool b) {
+        always_reopen_console = b;
+}
index 9cacbb6b70f58f9d57b829537eb5436ea2d96a55..72714e02e5625992241e271537dd9041af0c909a 100644 (file)
@@ -220,6 +220,7 @@ LogTarget log_target_from_string(const char *s) _pure_;
 void log_received_signal(int level, const struct signalfd_siginfo *si);
 
 void log_set_upgrade_syslog_to_journal(bool b);
+void log_set_always_reopen_console(bool b);
 
 int log_syntax_internal(
                 const char *unit,
index f703e7f145538cae1c13dd49c9df4180d6dd82d3..8592a428d58122a012549650eaa1f3d0d3086168 100644 (file)
@@ -154,7 +154,7 @@ int proc_cmdline_get_key(const char *key, unsigned flags, char **value) {
          *
          * c) The "value" parameter is NULL. In this case a search for the exact "key" parameter is performed.
          *
-         * In all three cases, > 0 is returned if the key is found, 0 if not.*/
+         * In all three cases, > 0 is returned if the key is found, 0 if not. */
 
         if (isempty(key))
                 return -EINVAL;
index 87e5586027840f060ea1bcf51f70154975e9cfec..0df3fed64064e0f9b171e4ed38fc2bd268dd944c 100644 (file)
@@ -311,7 +311,7 @@ int rename_process(const char name[]) {
 
         /* Third step, completely replace the argv[] array the kernel maintains for us. This requires privileges, but
          * has the advantage that the argv[] array is exactly what we want it to be, and not filled up with zeros at
-         * the end. This is the best option for changing /proc/self/cmdline.*/
+         * the end. This is the best option for changing /proc/self/cmdline. */
         if (mm_size < l+1) {
                 size_t nn_size;
                 char *nn;
index 60f92e63733c3ae040fa350e2080ecb227188783..0eec868eed1f5e0dc46288eadf16b89830d49b7c 100644 (file)
@@ -564,6 +564,9 @@ int strv_extend_front(char ***l, const char *value) {
 
         /* Like strv_extend(), but prepends rather than appends the new entry */
 
+        if (!value)
+                return 0;
+
         n = strv_length(*l);
 
         /* Increase and overflow check. */
@@ -571,12 +574,9 @@ int strv_extend_front(char ***l, const char *value) {
         if (m < n)
                 return -ENOMEM;
 
-        if (value) {
-                v = strdup(value);
-                if (!v)
-                        return -ENOMEM;
-        } else
-                v = NULL;
+        v = strdup(value);
+        if (!v)
+                return -ENOMEM;
 
         c = realloc_multiply(*l, sizeof(char*), m);
         if (!c) {
index 7d6c008ea1177f6319459a590f2498c0f93ceec4..155bf278b2e444072e05d60916070f9d3036e3fd 100644 (file)
 
 #include "alloc-util.h"
 #include "blkid-util.h"
+#include "copy.h"
 #include "dirent-util.h"
 #include "efivars.h"
 #include "fd-util.h"
 #include "fileio.h"
+#include "fs-util.h"
 #include "locale-util.h"
 #include "parse-util.h"
 #include "rm-rf.h"
+#include "stat-util.h"
 #include "string-util.h"
 #include "strv.h"
 #include "umask-util.h"
 #include "util.h"
 #include "verbs.h"
 #include "virt.h"
-#include "stat-util.h"
 
 static char *arg_path = NULL;
 static bool arg_touch_variables = true;
@@ -456,16 +458,16 @@ static int compare_version(const char *a, const char *b) {
         return strverscmp(a, b);
 }
 
-static int version_check(int fd, const char *from, const char *to) {
+static int version_check(int fd_from, const char *from, int fd_to, const char *to) {
         _cleanup_free_ char *a = NULL, *b = NULL;
-        _cleanup_close_ int fd2 = -1;
         int r;
 
-        assert(fd >= 0);
+        assert(fd_from >= 0);
         assert(from);
+        assert(fd_to >= 0);
         assert(to);
 
-        r = get_file_version(fd, &a);
+        r = get_file_version(fd_from, &a);
         if (r < 0)
                 return r;
         if (r == 0) {
@@ -473,15 +475,7 @@ static int version_check(int fd, const char *from, const char *to) {
                 return -EINVAL;
         }
 
-        fd2 = open(to, O_RDONLY|O_CLOEXEC);
-        if (fd2 < 0) {
-                if (errno == ENOENT)
-                        return 0;
-
-                return log_error_errno(errno, "Failed to open \"%s\" for reading: %m", to);
-        }
-
-        r = get_file_version(fd2, &b);
+        r = get_file_version(fd_to, &b);
         if (r < 0)
                 return r;
         if (r == 0 || compare_product(a, b) != 0) {
@@ -497,90 +491,59 @@ static int version_check(int fd, const char *from, const char *to) {
         return 0;
 }
 
-static int copy_file(const char *from, const char *to, bool force) {
-        _cleanup_fclose_ FILE *f = NULL, *g = NULL;
-        char *p;
+static int copy_file_with_version_check(const char *from, const char *to, bool force) {
+        _cleanup_close_ int fd_from = -1, fd_to = -1;
+        _cleanup_free_ char *t = NULL;
         int r;
-        struct timespec t[2];
-        struct stat st;
 
-        assert(from);
-        assert(to);
-
-        f = fopen(from, "re");
-        if (!f)
+        fd_from = open(from, O_RDONLY|O_CLOEXEC|O_NOCTTY);
+        if (fd_from < 0)
                 return log_error_errno(errno, "Failed to open \"%s\" for reading: %m", from);
 
         if (!force) {
-                /* If this is an update, then let's compare versions first */
-                r = version_check(fileno(f), from, to);
-                if (r < 0)
-                        return r;
-        }
-
-        p = strjoina(to, "~");
-        g = fopen(p, "wxe");
-        if (!g) {
-                /* Directory doesn't exist yet? Then let's skip this... */
-                if (!force && errno == ENOENT)
-                        return 0;
-
-                return log_error_errno(errno, "Failed to open \"%s\" for writing: %m", to);
-        }
+                fd_to = open(to, O_RDONLY|O_CLOEXEC|O_NOCTTY);
+                if (fd_to < 0) {
+                        if (errno != -ENOENT)
+                                return log_error_errno(errno, "Failed to open \"%s\" for reading: %m", to);
+                } else {
+                        r = version_check(fd_from, from, fd_to, to);
+                        if (r < 0)
+                                return r;
 
-        rewind(f);
-        do {
-                size_t k;
-                uint8_t buf[32*1024];
+                        if (lseek(fd_from, 0, SEEK_SET) == (off_t) -1)
+                                return log_error_errno(errno, "Failed to seek in \%s\": %m", from);
 
-                k = fread(buf, 1, sizeof(buf), f);
-                if (ferror(f)) {
-                        r = log_error_errno(EIO, "Failed to read \"%s\": %m", from);
-                        goto error;
+                        fd_to = safe_close(fd_to);
                 }
+        }
 
-                if (k == 0)
-                        break;
-
-                fwrite(buf, 1, k, g);
-                if (ferror(g)) {
-                        r = log_error_errno(EIO, "Failed to write \"%s\": %m", to);
-                        goto error;
-                }
-        } while (!feof(f));
+        r = tempfn_random(to, NULL, &t);
+        if (r < 0)
+                return log_oom();
 
-        r = fflush_and_check(g);
-        if (r < 0) {
-                log_error_errno(r, "Failed to write \"%s\": %m", to);
-                goto error;
+        RUN_WITH_UMASK(0000) {
+                fd_to = open(t, O_WRONLY|O_CREAT|O_CLOEXEC|O_EXCL|O_NOFOLLOW, 0644);
+                if (fd_to < 0)
+                        return log_error_errno(errno, "Failed to open \"%s\" for writing: %m", t);
         }
 
-        r = fstat(fileno(f), &st);
+        r = copy_bytes(fd_from, fd_to, (uint64_t) -1, COPY_REFLINK);
         if (r < 0) {
-                r = log_error_errno(errno, "Failed to get file timestamps of \"%s\": %m", from);
-                goto error;
+                unlink(t);
+                return log_error_errno(errno, "Failed to copy data from \"%s\" to \"%s\": %m", from, t);
         }
 
-        t[0] = st.st_atim;
-        t[1] = st.st_mtim;
+        (void) copy_times(fd_from, fd_to);
 
-        r = futimens(fileno(g), t);
+        r = renameat(AT_FDCWD, t, AT_FDCWD, to);
         if (r < 0) {
-                r = log_error_errno(errno, "Failed to set file timestamps on \"%s\": %m", p);
-                goto error;
-        }
-
-        if (rename(p, to) < 0) {
-                r = log_error_errno(errno, "Failed to rename \"%s\" to \"%s\": %m", p, to);
-                goto error;
+                (void) unlink_noerrno(t);
+                return log_error_errno(errno, "Failed to rename \"%s\" to \"%s\": %m", t, to);
         }
 
         log_info("Copied \"%s\" to \"%s\".", from, to);
-        return 0;
 
-error:
-        (void) unlink(p);
-        return r;
+        return 0;
 }
 
 static int mkdir_one(const char *prefix, const char *suffix) {
@@ -624,7 +587,7 @@ static int copy_one_file(const char *esp_path, const char *name, bool force) {
 
         p = strjoina(BOOTLIBDIR "/", name);
         q = strjoina(esp_path, "/EFI/systemd/", name);
-        r = copy_file(p, q, force);
+        r = copy_file_with_version_check(p, q, force);
 
         if (startswith(name, "systemd-boot")) {
                 int k;
@@ -634,7 +597,7 @@ static int copy_one_file(const char *esp_path, const char *name, bool force) {
                 v = strjoina(esp_path, "/EFI/BOOT/BOOT", name + strlen("systemd-boot"));
                 ascii_strupper(strrchr(v, '/') + 1);
 
-                k = copy_file(p, v, force);
+                k = copy_file_with_version_check(p, v, force);
                 if (k < 0 && r == 0)
                         r = k;
         }
@@ -930,20 +893,31 @@ static int remove_variables(sd_id128_t uuid, const char *path, bool in_order) {
 
 static int install_loader_config(const char *esp_path) {
 
-        _cleanup_fclose_ FILE *f = NULL;
         char machine_string[SD_ID128_STRING_MAX];
+        _cleanup_(unlink_and_freep) char *t = NULL;
+        _cleanup_fclose_ FILE *f = NULL;
         sd_id128_t machine_id;
         const char *p;
-        int r;
+        int r, fd;
 
         r = sd_id128_get_machine(&machine_id);
         if (r < 0)
                 return log_error_errno(r, "Failed to get machine did: %m");
 
         p = strjoina(esp_path, "/loader/loader.conf");
-        f = fopen(p, "wxe");
-        if (!f)
-                return log_error_errno(errno, "Failed to open loader.conf for writing: %m");
+
+        if (access(p, F_OK) >= 0) /* Silently skip creation if the file already exists (early check) */
+                return 0;
+
+        fd = open_tmpfile_linkable(p, O_WRONLY|O_CLOEXEC, &t);
+        if (fd < 0)
+                return log_error_errno(fd, "Failed to open \"%s\" for writing: %m", p);
+
+        f = fdopen(fd, "we");
+        if (!f) {
+                safe_close(fd);
+                return log_oom();
+        }
 
         fprintf(f, "#timeout 3\n");
         fprintf(f, "default %s-*\n", sd_id128_to_string(machine_id, machine_string));
@@ -952,7 +926,15 @@ static int install_loader_config(const char *esp_path) {
         if (r < 0)
                 return log_error_errno(r, "Failed to write \"%s\": %m", p);
 
-        return 0;
+        r = link_tmpfile(fd, t, p);
+        if (r == -EEXIST)
+                return 0; /* Silently skip creation if the file exists now (recheck) */
+        if (r < 0)
+                return log_error_errno(r, "Failed to move \"%s\" into place: %m", p);
+
+        t = mfree(t);
+
+        return 1;
 }
 
 static int help(int argc, char *argv[], void *userdata) {
index 7cc54a8cddc1097feeda385333745f5cc7ef559f..681e783f2e2ee423a0dc1d2fd394f7f7d081ea26 100644 (file)
@@ -1787,7 +1787,7 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) {
 
         config_title_generate(&config);
 
-        /* select entry by configured pattern or EFI LoaderDefaultEntry= variable*/
+        /* select entry by configured pattern or EFI LoaderDefaultEntry= variable */
         config_default_entry_select(&config);
 
         /* if no configured entry to select from was found, enable the menu */
index 5574c145553edc3f005837b88db971e13d3ef885..1b746a0e13d40c4a0828252516c007b8c365fe49 100644 (file)
@@ -158,7 +158,7 @@ static int parse_argv(int argc, char *argv[]) {
 
 static void show_cg_info(const char *controller, const char *path) {
 
-        if (cg_all_unified() <= 0 && controller && !streq(controller, SYSTEMD_CGROUP_CONTROLLER))
+        if (cg_all_unified() == 0 && controller && !streq(controller, SYSTEMD_CGROUP_CONTROLLER))
                 printf("Controller %s; ", controller);
 
         printf("Control group %s:\n", isempty(path) ? "/" : path);
index 50ac6a58b0aa2870299493aa59ec30b612d3dd38..a1c0f48c8906c69aee2ae9182816376b027bc8d9 100644 (file)
@@ -133,12 +133,16 @@ static int process(
                 Group **ret) {
 
         Group *g;
-        int r;
+        int r, all_unified;
 
         assert(controller);
         assert(path);
         assert(a);
 
+        all_unified = cg_all_unified();
+        if (all_unified < 0)
+                return all_unified;
+
         g = hashmap_get(a, path);
         if (!g) {
                 g = hashmap_get(b, path);
@@ -214,7 +218,7 @@ static int process(
                 uint64_t new_usage;
                 nsec_t timestamp;
 
-                if (cg_all_unified() > 0) {
+                if (all_unified) {
                         const char *keys[] = { "usage_usec", NULL };
                         _cleanup_free_ char *val = NULL;
 
@@ -274,10 +278,10 @@ static int process(
         } else if (streq(controller, "memory")) {
                 _cleanup_free_ char *p = NULL, *v = NULL;
 
-                if (cg_all_unified() <= 0)
-                        r = cg_get_path(controller, path, "memory.usage_in_bytes", &p);
-                else
+                if (all_unified)
                         r = cg_get_path(controller, path, "memory.current", &p);
+                else
+                        r = cg_get_path(controller, path, "memory.usage_in_bytes", &p);
                 if (r < 0)
                         return r;
 
@@ -294,15 +298,14 @@ static int process(
                 if (g->memory > 0)
                         g->memory_valid = true;
 
-        } else if ((streq(controller, "io") && cg_all_unified() > 0) ||
-                   (streq(controller, "blkio") && cg_all_unified() <= 0)) {
+        } else if ((streq(controller, "io") && all_unified) ||
+                   (streq(controller, "blkio") && !all_unified)) {
                 _cleanup_fclose_ FILE *f = NULL;
                 _cleanup_free_ char *p = NULL;
-                bool unified = cg_all_unified() > 0;
                 uint64_t wr = 0, rd = 0;
                 nsec_t timestamp;
 
-                r = cg_get_path(controller, path, unified ? "io.stat" : "blkio.io_service_bytes", &p);
+                r = cg_get_path(controller, path, all_unified ? "io.stat" : "blkio.io_service_bytes", &p);
                 if (r < 0)
                         return r;
 
@@ -325,7 +328,7 @@ static int process(
                         l += strcspn(l, WHITESPACE);
                         l += strspn(l, WHITESPACE);
 
-                        if (unified) {
+                        if (all_unified) {
                                 while (!isempty(l)) {
                                         if (sscanf(l, "rbytes=%" SCNu64, &k))
                                                 rd += k;
index 5789e2aa82536be66f10d30bb7112b39884ae917..774b832a63c057fdd73a3b4b461bf2454c0818ba 100644 (file)
@@ -859,8 +859,7 @@ static void cgroup_context_apply(Unit *u, CGroupMask mask, ManagerState state) {
 
         if ((mask & CGROUP_MASK_MEMORY) && !is_root) {
                 if (cg_all_unified() > 0) {
-                        uint64_t max;
-                        uint64_t swap_max = CGROUP_LIMIT_MAX;
+                        uint64_t max, swap_max = CGROUP_LIMIT_MAX;
 
                         if (cgroup_context_has_unified_memory_config(c)) {
                                 max = c->memory_max;
@@ -1260,9 +1259,9 @@ int unit_watch_cgroup(Unit *u) {
                 return 0;
 
         /* Only applies to the unified hierarchy */
-        r = cg_unified(SYSTEMD_CGROUP_CONTROLLER);
+        r = cg_unified_controller(SYSTEMD_CGROUP_CONTROLLER);
         if (r < 0)
-                return log_unit_error_errno(u, r, "Failed detect whether the unified hierarchy is used: %m");
+                return log_error_errno(r, "Failed to determine whether the name=systemd hierarchy is unified: %m");
         if (r == 0)
                 return 0;
 
@@ -1673,6 +1672,8 @@ static int unit_watch_pids_in_path(Unit *u, const char *path) {
 }
 
 int unit_watch_all_pids(Unit *u) {
+        int r;
+
         assert(u);
 
         /* Adds all PIDs from our cgroup to the set of PIDs we
@@ -1683,7 +1684,10 @@ int unit_watch_all_pids(Unit *u) {
         if (!u->cgroup_path)
                 return -ENOENT;
 
-        if (cg_unified(SYSTEMD_CGROUP_CONTROLLER) > 0) /* On unified we can use proper notifications */
+        r = cg_unified_controller(SYSTEMD_CGROUP_CONTROLLER);
+        if (r < 0)
+                return r;
+        if (r > 0) /* On unified we can use proper notifications */
                 return 0;
 
         return unit_watch_pids_in_path(u, u->cgroup_path);
@@ -1756,7 +1760,7 @@ static int on_cgroup_inotify_event(sd_event_source *s, int fd, uint32_t revents,
 int manager_setup_cgroup(Manager *m) {
         _cleanup_free_ char *path = NULL;
         CGroupController c;
-        int r, all_unified, systemd_unified;
+        int r, all_unified;
         char *e;
 
         assert(m);
@@ -1793,25 +1797,30 @@ int manager_setup_cgroup(Manager *m) {
         if (r < 0)
                 return log_error_errno(r, "Cannot find cgroup mount point: %m");
 
-        all_unified = cg_all_unified();
-        systemd_unified = cg_unified(SYSTEMD_CGROUP_CONTROLLER);
-
-        if (all_unified < 0 || systemd_unified < 0)
-                return log_error_errno(all_unified < 0 ? all_unified : systemd_unified,
-                                       "Couldn't determine if we are running in the unified hierarchy: %m");
+        r = cg_unified_flush();
+        if (r < 0)
+                return log_error_errno(r, "Couldn't determine if we are running in the unified hierarchy: %m");
 
-        if (all_unified > 0)
+        all_unified = cg_all_unified();
+        if (r < 0)
+                return log_error_errno(r, "Couldn't determine whether we are in all unified mode: %m");
+        if (r > 0)
                 log_debug("Unified cgroup hierarchy is located at %s.", path);
-        else if (systemd_unified > 0)
-                log_debug("Unified cgroup hierarchy is located at %s. Controllers are on legacy hierarchies.", path);
-        else
-                log_debug("Using cgroup controller " SYSTEMD_CGROUP_CONTROLLER ". File system hierarchy is at %s.", path);
+        else {
+                r = cg_unified_controller(SYSTEMD_CGROUP_CONTROLLER);
+                if (r < 0)
+                        return log_error_errno(r, "Failed to determine whether systemd's own controller is in unified mode: %m");
+                if (r > 0)
+                        log_debug("Unified cgroup hierarchy is located at %s. Controllers are on legacy hierarchies.", path);
+                else
+                        log_debug("Using cgroup controller " SYSTEMD_CGROUP_CONTROLLER_LEGACY ". File system hierarchy is at %s.", path);
+        }
 
         if (!m->test_run) {
                 const char *scope_path;
 
                 /* 3. Install agent */
-                if (systemd_unified) {
+                if (cg_unified_controller(SYSTEMD_CGROUP_CONTROLLER) > 0) {
 
                         /* In the unified hierarchy we can get
                          * cgroup empty notifications via inotify. */
@@ -1997,10 +2006,13 @@ int unit_get_memory_current(Unit *u, uint64_t *ret) {
         if ((u->cgroup_realized_mask & CGROUP_MASK_MEMORY) == 0)
                 return -ENODATA;
 
-        if (cg_all_unified() <= 0)
-                r = cg_get_attribute("memory", u->cgroup_path, "memory.usage_in_bytes", &v);
-        else
+        r = cg_all_unified();
+        if (r < 0)
+                return r;
+        if (r > 0)
                 r = cg_get_attribute("memory", u->cgroup_path, "memory.current", &v);
+        else
+                r = cg_get_attribute("memory", u->cgroup_path, "memory.usage_in_bytes", &v);
         if (r == -ENOENT)
                 return -ENODATA;
         if (r < 0)
@@ -2042,7 +2054,10 @@ static int unit_get_cpu_usage_raw(Unit *u, nsec_t *ret) {
         if (!u->cgroup_path)
                 return -ENODATA;
 
-        if (cg_all_unified() > 0) {
+        r = cg_all_unified();
+        if (r < 0)
+                return r;
+        if (r > 0) {
                 const char *keys[] = { "usage_usec", NULL };
                 _cleanup_free_ char *val = NULL;
                 uint64_t us;
index 3c6b18229c841d637b6473a49acc7b598b2335da..bcf9ea5f25a07379d1aad01d4be821848b17e126 100644 (file)
@@ -1414,10 +1414,17 @@ int main(int argc, char *argv[]) {
 
         log_set_upgrade_syslog_to_journal(true);
 
-        /* Disable the umask logic */
-        if (getpid() == 1)
+        if (getpid() == 1) {
+                /* Disable the umask logic */
                 umask(0);
 
+                /* Always reopen /dev/console when running as PID 1 or one of its pre-execve() children. This is
+                 * important so that we never end up logging to any foreign stderr, for example if we have to log in a
+                 * child process right before execve()'ing the actual binary, at a point in time where socket
+                 * activation stderr/stdout area already set up. */
+                log_set_always_reopen_console(true);
+        }
+
         if (getpid() == 1 && detect_container() <= 0) {
 
                 /* Running outside of a container as PID 1 */
index d3f6efc91c49b613a7adc97a4515bb1ba65be831..cff38e28deaf4479761532def049f10ed7579b0e 100644 (file)
@@ -776,7 +776,10 @@ static int manager_setup_cgroups_agent(Manager *m) {
         if (!MANAGER_IS_SYSTEM(m))
                 return 0;
 
-        if (cg_unified(SYSTEMD_CGROUP_CONTROLLER) > 0) /* We don't need this anymore on the unified hierarchy */
+        r = cg_unified_controller(SYSTEMD_CGROUP_CONTROLLER);
+        if (r < 0)
+                return log_error_errno(r, "Failed to determine whether unified cgroups hierarchy is used: %m");
+        if (r > 0) /* We don't need this anymore on the unified hierarchy */
                 return 0;
 
         if (m->cgroups_agent_fd < 0) {
index 9c2bf3a0efec1d4293d34ba6dbbcdb3389962786..7295efbf3148b4082c764c80aaaa270ee246c003 100644 (file)
@@ -96,15 +96,15 @@ static const MountPoint mount_table[] = {
         { "tmpfs",       "/run",                      "tmpfs",      "mode=755",                MS_NOSUID|MS_NODEV|MS_STRICTATIME,
           NULL,          MNT_FATAL|MNT_IN_CONTAINER },
         { "cgroup",      "/sys/fs/cgroup",            "cgroup2",    NULL,                      MS_NOSUID|MS_NOEXEC|MS_NODEV,
-          cg_is_unified_wanted, MNT_FATAL|MNT_IN_CONTAINER },
+          cg_is_unified_wanted, MNT_IN_CONTAINER },
         { "tmpfs",       "/sys/fs/cgroup",            "tmpfs",      "mode=755",                MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_STRICTATIME,
           cg_is_legacy_wanted, MNT_FATAL|MNT_IN_CONTAINER },
-        { "cgroup",      "/sys/fs/cgroup/systemd",    "cgroup2",    NULL,                      MS_NOSUID|MS_NOEXEC|MS_NODEV,
-          cg_is_unified_systemd_controller_wanted, MNT_IN_CONTAINER },
+        { "cgroup",      "/sys/fs/cgroup/unified",    "cgroup2",    NULL,                      MS_NOSUID|MS_NOEXEC|MS_NODEV,
+          cg_is_hybrid_wanted, MNT_IN_CONTAINER },
         { "cgroup",      "/sys/fs/cgroup/systemd",    "cgroup",     "none,name=systemd,xattr", MS_NOSUID|MS_NOEXEC|MS_NODEV,
-          cg_is_legacy_systemd_controller_wanted, MNT_IN_CONTAINER           },
+          cg_is_legacy_wanted, MNT_IN_CONTAINER     },
         { "cgroup",      "/sys/fs/cgroup/systemd",    "cgroup",     "none,name=systemd",       MS_NOSUID|MS_NOEXEC|MS_NODEV,
-          cg_is_legacy_systemd_controller_wanted, MNT_FATAL|MNT_IN_CONTAINER },
+          cg_is_legacy_wanted, MNT_FATAL|MNT_IN_CONTAINER },
         { "pstore",      "/sys/fs/pstore",            "pstore",     NULL,                      MS_NOSUID|MS_NOEXEC|MS_NODEV,
           NULL,          MNT_NONE                   },
 #ifdef ENABLE_EFI
index 75dca5b791f477b55c808b77fa6f838358b0235d..4f29217bc4a342e8cf56b4e6dd7f478078b6f681 100644 (file)
@@ -799,7 +799,7 @@ static int make_read_only(MountEntry *m, char **blacklist) {
 
         if (mount_entry_read_only(m))
                 r = bind_remount_recursive(mount_entry_path(m), true, blacklist);
-        else if (m->mode == PRIVATE_DEV) { /* Superblock can be readonly but the submounts can't*/
+        else if (m->mode == PRIVATE_DEV) { /* Superblock can be readonly but the submounts can't */
                 if (mount(NULL, mount_entry_path(m), NULL, MS_REMOUNT|DEV_MOUNT_OPTIONS|MS_RDONLY, NULL) < 0)
                         r = -errno;
         } else
index 9540fb67d98f44b5c5be1fc8ae5800e31cd704e5..a1d5c1cfd541122bcfbe607009aadd6f484de5ba 100644 (file)
@@ -475,7 +475,7 @@ static void scope_sigchld_event(Unit *u, pid_t pid, int code, int status) {
 
         /* If the PID set is empty now, then let's finish this off
            (On unified we use proper notifications) */
-        if (cg_unified(SYSTEMD_CGROUP_CONTROLLER) <= 0 && set_isempty(u->pids))
+        if (cg_unified_controller(SYSTEMD_CGROUP_CONTROLLER) == 0 && set_isempty(u->pids))
                 scope_notify_cgroup_empty_event(u);
 }
 
index 54074ff7bcc6da5bc4f79d5023f5299accd9d014..5581ec8b0620020f87352769b4a9d681a7d85f13 100644 (file)
@@ -2938,7 +2938,7 @@ static void service_sigchld_event(Unit *u, pid_t pid, int code, int status) {
 
         /* If the PID set is empty now, then let's finish this off
            (On unified we use proper notifications) */
-        if (cg_unified(SYSTEMD_CGROUP_CONTROLLER) <= 0 && set_isempty(u->pids))
+        if (cg_unified_controller(SYSTEMD_CGROUP_CONTROLLER) == 0 && set_isempty(u->pids))
                 service_notify_cgroup_empty_event(u);
 }
 
index 84b7a1a82d3d1ac609236b9bbe2f76bdef6d842b..c4da227e0931144cd74c2e143bbbd78f68b869d1 100644 (file)
@@ -1260,7 +1260,7 @@ static int usbffs_address_create(const char *path) {
         if (fstat(fd, &st) < 0)
                 return -errno;
 
-        /* Check whether this is a regular file (ffs endpoint)*/
+        /* Check whether this is a regular file (ffs endpoint) */
         if (!S_ISREG(st.st_mode))
                 return -EEXIST;
 
index bb05d2abfbd602a2977ff6d683279397adb17626..174dd4281979f143519e902a043d9ffd7e1cc7d3 100644 (file)
@@ -3895,10 +3895,10 @@ int unit_kill_context(
                          * should not exist in non-delegated units. On
                          * the unified hierarchy that's different,
                          * there we get proper events. Hence rely on
-                         * them.*/
+                         * them. */
 
-                        if  (cg_unified(SYSTEMD_CGROUP_CONTROLLER) > 0 ||
-                             (detect_container() == 0 && !unit_cgroup_delegate(u)))
+                        if (cg_unified_controller(SYSTEMD_CGROUP_CONTROLLER) > 0 ||
+                            (detect_container() == 0 && !unit_cgroup_delegate(u)))
                                 wait_for_exit = true;
 
                         if (send_sighup) {
index 29fb71c8dd7109333a7fc127f2755af64075df13..4ac98d8163d5fd2aa3ea3682ca63b513990755ee 100644 (file)
@@ -50,6 +50,8 @@
 #include "user-util.h"
 #include "util.h"
 
+static usec_t arg_since = USEC_INFINITY, arg_until = USEC_INFINITY;
+
 static enum {
         ACTION_NONE,
         ACTION_INFO,
@@ -128,11 +130,12 @@ static void help(void) {
                "     --no-pager      Do not pipe output into a pager\n"
                "     --no-legend     Do not print the column headers.\n"
                "  -1                 Show information about most recent entry only\n"
+               "  -S --since=DATE    Only print coredumps since the date\n"
+               "  -U --until=DATE    Only print coredumps until the date\n"
                "  -r --reverse       Show the newest entries first\n"
                "  -F --field=FIELD   List all values a certain field takes\n"
                "  -o --output=FILE   Write output to FILE\n"
                "  -D --directory=DIR Use journal files from directory\n\n"
-
                "Commands:\n"
                "  list [MATCHES...]  List available coredumps (default)\n"
                "  info [MATCHES...]  Show detailed information about one or more coredumps\n"
@@ -148,7 +151,7 @@ static int parse_argv(int argc, char *argv[]) {
                 ARG_NO_LEGEND,
         };
 
-        int c;
+        int c, r;
 
         static const struct option options[] = {
                 { "help",         no_argument,       NULL, 'h'           },
@@ -159,15 +162,16 @@ static int parse_argv(int argc, char *argv[]) {
                 { "field",        required_argument, NULL, 'F'           },
                 { "directory",    required_argument, NULL, 'D'           },
                 { "reverse",      no_argument,       NULL, 'r'           },
+                { "since",        required_argument, NULL, 'S'           },
+                { "until",        required_argument, NULL, 'U'           },
                 {}
         };
 
         assert(argc >= 0);
         assert(argv);
 
-        while ((c = getopt_long(argc, argv, "ho:F:1D:r", options, NULL)) >= 0)
+        while ((c = getopt_long(argc, argv, "ho:F:1D:S:U:r", options, NULL)) >= 0)
                 switch(c) {
-
                 case 'h':
                         arg_action = ACTION_NONE;
                         help();
@@ -197,6 +201,18 @@ static int parse_argv(int argc, char *argv[]) {
 
                         break;
 
+                case 'S':
+                        r = parse_timestamp(optarg, &arg_since);
+                        if (r < 0)
+                                return log_error_errno(r, "Failed to parse timestamp: %s", optarg);
+                        break;
+
+                case 'U':
+                        r = parse_timestamp(optarg, &arg_until);
+                        if (r < 0)
+                                return log_error_errno(r, "Failed to parse timestamp: %s", optarg);
+                        break;
+
                 case 'F':
                         if (arg_field) {
                                 log_error("cannot use --field/-F more than once");
@@ -224,6 +240,12 @@ static int parse_argv(int argc, char *argv[]) {
                         assert_not_reached("Unhandled option");
                 }
 
+        if (arg_since != USEC_INFINITY && arg_until != USEC_INFINITY &&
+            arg_since > arg_until) {
+                log_error("--since= must be before --until=.");
+                return -EINVAL;
+        }
+
         if (optind < argc) {
                 const char *cmd = argv[optind++];
                 if (streq(cmd, "list"))
@@ -610,18 +632,52 @@ static int dump_list(sd_journal *j) {
 
                 return print_entry(j, 0);
         } else {
-                if (!arg_reverse) {
-                        SD_JOURNAL_FOREACH(j) {
-                                r = print_entry(j, n_found++);
+                if (arg_since != USEC_INFINITY && !arg_reverse)
+                        r = sd_journal_seek_realtime_usec(j, arg_since);
+                else if (arg_until != USEC_INFINITY && arg_reverse)
+                        r = sd_journal_seek_realtime_usec(j, arg_until);
+                else if (arg_reverse)
+                        r = sd_journal_seek_tail(j);
+                else
+                        r = sd_journal_seek_head(j);
+                if (r < 0)
+                        return log_error_errno(r, "Failed to seek to date: %m");
+
+                for (;;) {
+                        if (!arg_reverse)
+                                r = sd_journal_next(j);
+                        else
+                                r = sd_journal_previous(j);
+
+                        if (r < 0)
+                                return log_error_errno(r, "Failed to iterate through journal: %m");
+
+                        if (r == 0)
+                                break;
+
+                        if (arg_until != USEC_INFINITY && !arg_reverse) {
+                                usec_t usec;
+
+                                r = sd_journal_get_realtime_usec(j, &usec);
                                 if (r < 0)
-                                        return r;
+                                        return log_error_errno(r, "Failed to determine timestamp: %m");
+                                if (usec > arg_until)
+                                        continue;
                         }
-                } else {
-                        SD_JOURNAL_FOREACH_BACKWARDS(j) {
-                                r = print_entry(j, n_found++);
+
+                        if (arg_since != USEC_INFINITY && arg_reverse) {
+                                usec_t usec;
+
+                                r = sd_journal_get_realtime_usec(j, &usec);
                                 if (r < 0)
-                                        return r;
+                                        return log_error_errno(r, "Failed to determine timestamp: %m");
+                                if (usec < arg_since)
+                                        continue;
                         }
+
+                        r = print_entry(j, n_found++);
+                        if (r < 0)
+                                return r;
                 }
 
                 if (!arg_field && n_found <= 0) {
@@ -916,7 +972,7 @@ static int check_units_active(void) {
         while ((r = sd_bus_message_read(
                                 reply, "(ssssssouso)",
                                 NULL,  NULL,  NULL,  &state,  NULL,
-                                NULL,  NULL,  NULL,  NULL,  NULL) > 0))
+                                NULL,  NULL,  NULL,  NULL,  NULL)) > 0)
                 if (!STR_IN_SET(state, "dead", "failed"))
                         c++;
 
index 59bd7d9e84642dd6b9305cb0ad797653038d8789..06564e94b16d7d1cf17f3980a7ac3c3b4d1066ea 100644 (file)
@@ -208,6 +208,14 @@ int main(int argc, char *argv[]) {
                 log_error_errno(r, "No root partition for specified root hash found in %s.", arg_image);
                 goto finish;
         }
+        if (r == -ENOTUNIQ) {
+                log_error_errno(r, "Multiple suitable root partitions found in image %s.", arg_image);
+                goto finish;
+        }
+        if (r == -ENXIO) {
+                log_error_errno(r, "No suitable root partition found in image %s.", arg_image);
+                goto finish;
+        }
         if (r < 0) {
                 log_error_errno(r, "Failed to dissect image: %m");
                 goto finish;
index 734e1560e67f61c9a25c40b66a817cc7d50d25ec..0e8f3fb918fb2ad135cfad98a501c9eff5144080 100644 (file)
@@ -400,7 +400,7 @@ int curl_header_strdup(const void *contents, size_t sz, const char *field, char
                 sz--;
         }
 
-        /* Truncate trailing whitespace*/
+        /* Truncate trailing whitespace */
         while (sz > 0 && strchr(WHITESPACE, p[sz-1]))
                 sz--;
 
index ef87b176fabebd540f5bfab9203370e8cca00fdf..a6ccb679a8413b1096416050d37cba02522b78d5 100644 (file)
@@ -3283,7 +3283,7 @@ int journal_file_rotate(JournalFile **f, bool compress, bool seal, Set *deferred
                 return -EINVAL;
 
         /* Is this a journal file that was passed to us as fd? If so, we synthesized a path name for it, and we refuse
-         * rotation, since we don't know the actual path, and couldn't rename the file hence.*/
+         * rotation, since we don't know the actual path, and couldn't rename the file hence. */
         if (path_startswith(old_file->path, "/proc/self/fd"))
                 return -EINVAL;
 
index 451f16483f38d7de89d14fd2d9d37820e8dfb534..6466e46cccfaba2fd98a00ca0c77c9aa3ba90562 100644 (file)
@@ -760,7 +760,8 @@ static void dispatch_message_real(
                 const char *label, size_t label_len,
                 const char *unit_id,
                 int priority,
-                pid_t object_pid) {
+                pid_t object_pid,
+                char *cgroup) {
 
         char    pid[sizeof("_PID=") + DECIMAL_STR_MAX(pid_t)],
                 uid[sizeof("_UID=") + DECIMAL_STR_MAX(uid_t)],
@@ -846,7 +847,12 @@ static void dispatch_message_real(
                 }
 #endif
 
-                r = cg_pid_get_path_shifted(ucred->pid, s->cgroup_root, &c);
+                r = 0;
+                if (cgroup)
+                        c = cgroup;
+                else
+                        r = cg_pid_get_path_shifted(ucred->pid, s->cgroup_root, &c);
+
                 if (r >= 0) {
                         _cleanup_free_ char *raw_unit = NULL, *raw_slice = NULL;
                         char *session = NULL;
@@ -904,7 +910,8 @@ static void dispatch_message_real(
                                 }
                         }
 
-                        free(c);
+                        if (!cgroup)
+                                free(c);
                 } else if (unit_id) {
                         x = strjoina("_SYSTEMD_UNIT=", unit_id);
                         IOVEC_SET_STRING(iovec[n++], x);
@@ -1093,7 +1100,7 @@ void server_driver_message(Server *s, const char *message_id, const char *format
         ucred.gid = getgid();
 
         if (r >= 0)
-                dispatch_message_real(s, iovec, n, ELEMENTSOF(iovec), &ucred, NULL, NULL, 0, NULL, LOG_INFO, 0);
+                dispatch_message_real(s, iovec, n, ELEMENTSOF(iovec), &ucred, NULL, NULL, 0, NULL, LOG_INFO, 0, NULL);
 
         while (m < n)
                 free(iovec[m++].iov_base);
@@ -1107,7 +1114,7 @@ void server_driver_message(Server *s, const char *message_id, const char *format
                 n = 3;
                 IOVEC_SET_STRING(iovec[n++], "PRIORITY=4");
                 IOVEC_SET_STRING(iovec[n++], buf);
-                dispatch_message_real(s, iovec, n, ELEMENTSOF(iovec), &ucred, NULL, NULL, 0, NULL, LOG_INFO, 0);
+                dispatch_message_real(s, iovec, n, ELEMENTSOF(iovec), &ucred, NULL, NULL, 0, NULL, LOG_INFO, 0, NULL);
         }
 }
 
@@ -1124,7 +1131,7 @@ void server_dispatch_message(
         int rl, r;
         _cleanup_free_ char *path = NULL;
         uint64_t available = 0;
-        char *c;
+        char *c = NULL;
 
         assert(s);
         assert(iovec || n == 0);
@@ -1175,7 +1182,10 @@ void server_dispatch_message(
                                       NULL);
 
 finish:
-        dispatch_message_real(s, iovec, n, m, ucred, tv, label, label_len, unit_id, priority, object_pid);
+        /* restore cgroup path for logging */
+        if (c)
+                *c = '/';
+        dispatch_message_real(s, iovec, n, m, ucred, tv, label, label_len, unit_id, priority, object_pid, path);
 }
 
 int server_flush_to_var(Server *s, bool require_flag_file) {
index 0469393f3bc9ad1a59e82ab2c7dd6418ca545f4e..44a2cf5217315b6c87e3d3b384e9835bcec82acd 100644 (file)
@@ -109,7 +109,7 @@ static void test_decompress_startswith(int compression,
         size_t csize, usize = 0, len;
         int r;
 
-        log_info("/* testing decompress_startswith with %s on %.20s text*/",
+        log_info("/* testing decompress_startswith with %s on %.20s text */",
                  object_compressed_to_string(compression), data);
 
 #define BUFSIZE_1 512
index 02028bf28afb7a844909c8bd17eae5147abdbb4e..2e02b3fa66b6a5ec7da14e6775bd899009c0bd46 100644 (file)
@@ -58,7 +58,7 @@ int arp_network_bind_raw_socket(int ifindex, be32_t address, const struct ether_
                 BPF_STMT(BPF_ALU + BPF_XOR + BPF_X, 0),                                        /* A xor X */
                 BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, 0, 0, 1),                                  /* A == 0 ? */
                 BPF_STMT(BPF_RET + BPF_K, 0),                                                  /* ignore */
-                /* Sender Protocol Address or Target Protocol Address must be equal to the one we care about*/
+                /* Sender Protocol Address or Target Protocol Address must be equal to the one we care about */
                 BPF_STMT(BPF_LD + BPF_IMM, htobe32(address)),                                  /* A <- clients IP */
                 BPF_STMT(BPF_MISC + BPF_TAX, 0),                                               /* X <- A */
                 BPF_STMT(BPF_LD + BPF_W + BPF_ABS, offsetof(struct ether_arp, arp_spa)),       /* A <- SPA */
index 6bcd65de0afe243ae0830fffbd80b08566604c4b..430c58ae60780cf8e4284fb7e54850766d16d7e3 100644 (file)
@@ -98,14 +98,14 @@ static void test_receive_basic_packet(sd_event *e) {
 
         static const uint8_t frame[] = {
                 /* Ethernet header */
-                0x01, 0x80, 0xc2, 0x00, 0x00, 0x03,     /* Destination MAC*/
+                0x01, 0x80, 0xc2, 0x00, 0x00, 0x03,     /* Destination MAC */
                 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,     /* Source MAC */
                 0x88, 0xcc,                             /* Ethertype */
                 /* LLDP mandatory TLVs */
                 0x02, 0x07, 0x04, 0x00, 0x01, 0x02,     /* Chassis: MAC, 00:01:02:03:04:05 */
                 0x03, 0x04, 0x05,
                 0x04, 0x04, 0x05, 0x31, 0x2f, 0x33,     /* Port: interface name, "1/3" */
-                0x06, 0x02, 0x00, 0x78,                 /* TTL: 120 seconds*/
+                0x06, 0x02, 0x00, 0x78,                 /* TTL: 120 seconds */
                 /* LLDP optional TLVs */
                 0x08, 0x04, 0x50, 0x6f, 0x72, 0x74,     /* Port Description: "Port" */
                 0x0a, 0x03, 0x53, 0x59, 0x53,           /* System Name: "SYS" */
@@ -162,7 +162,7 @@ static void test_receive_incomplete_packet(sd_event *e) {
         sd_lldp_neighbor **neighbors;
         uint8_t frame[] = {
                 /* Ethernet header */
-                0x01, 0x80, 0xc2, 0x00, 0x00, 0x03,     /* Destination MAC*/
+                0x01, 0x80, 0xc2, 0x00, 0x00, 0x03,     /* Destination MAC */
                 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,     /* Source MAC */
                 0x88, 0xcc,                             /* Ethertype */
                 /* LLDP mandatory TLVs */
@@ -189,14 +189,14 @@ static void test_receive_oui_packet(sd_event *e) {
         sd_lldp_neighbor **neighbors;
         uint8_t frame[] = {
                 /* Ethernet header */
-                0x01, 0x80, 0xc2, 0x00, 0x00, 0x03,     /* Destination MAC*/
+                0x01, 0x80, 0xc2, 0x00, 0x00, 0x03,     /* Destination MAC */
                 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,     /* Source MAC */
                 0x88, 0xcc,                             /* Ethertype */
                 /* LLDP mandatory TLVs */
                 0x02, 0x07, 0x04, 0x00, 0x01, 0x02,     /* Chassis: MAC, 00:01:02:03:04:05 */
                 0x03, 0x04, 0x05,
                 0x04, 0x04, 0x05, 0x31, 0x2f, 0x33,     /* Port TLV: interface name, "1/3" */
-                0x06, 0x02, 0x00, 0x78,                 /* TTL: 120 seconds*/
+                0x06, 0x02, 0x00, 0x78,                 /* TTL: 120 seconds */
                 /* LLDP optional TLVs */
                 0xfe, 0x06, 0x00, 0x80, 0xc2, 0x01,     /* Port VLAN ID: 0x1234 */
                 0x12, 0x34,
index 6fdcfa41287d4dd5df3ab62c29ebd407741edaa9..64bd76a576ee7e1ba36492a4e744a29b6156d080 100644 (file)
@@ -31,7 +31,7 @@ int main(int argc, char *argv[]) {
         log_parse_environment();
         log_open();
 
-        if (cg_all_unified() == -ENOMEDIUM) {
+        if (cg_unified_flush() == -ENOMEDIUM) {
                 log_info("Skipping test: /sys/fs/cgroup/ not available");
                 return EXIT_TEST_SKIP;
         }
index 9fad388953f589e42c9d4765e0a5c2e02dc97119..f4783deef8dce10e594a09cdfbf83607ee8ee379 100644 (file)
@@ -34,7 +34,7 @@ struct sd_device {
         uint64_t properties_generation; /* changes whenever the properties are changed */
         uint64_t properties_iterator_generation; /* generation when iteration was started */
 
-        /* the subset of the properties that should be written to the db*/
+        /* the subset of the properties that should be written to the db */
         OrderedHashmap *properties_db;
 
         Hashmap *sysattr_values; /* cached sysattr values */
index a0fd8a3ac9e58d29711c046979da2d48771f98bb..129bfd2d806318a25622b66809570493b45a9560 100644 (file)
@@ -281,7 +281,7 @@ static int socket_recv_message(int fd, struct iovec *iov, uint32_t *_group, bool
                 else if (errno == EAGAIN)
                         log_debug("rtnl: no data in socket");
 
-                return (errno == EAGAIN || errno == EINTR) ? 0 : -errno;
+                return IN_SET(errno, EAGAIN, EINTR) ? 0 : -errno;
         }
 
         if (sender.nl.nl_pid != 0) {
@@ -292,7 +292,7 @@ static int socket_recv_message(int fd, struct iovec *iov, uint32_t *_group, bool
                         /* drop the message */
                         r = recvmsg(fd, &msg, 0);
                         if (r < 0)
-                                return (errno == EAGAIN || errno == EINTR) ? 0 : -errno;
+                                return IN_SET(errno, EAGAIN, EINTR) ? 0 : -errno;
                 }
 
                 return 0;
index 43114eb825c5390661319654e142470ad522c572..68435564deebc2f1a7e27959aef863609dc39b4e 100644 (file)
@@ -276,6 +276,10 @@ static int dispatch_rqueue(sd_netlink *rtnl, sd_netlink_message **message) {
         if (rtnl->rqueue_size <= 0) {
                 /* Try to read a new message */
                 r = socket_read_message(rtnl);
+                if (r == -ENOBUFS) { /* FIXME: ignore buffer overruns for now */
+                        log_debug_errno(r, "Got ENOBUFS from netlink socket, ignoring.");
+                        return 1;
+                }
                 if (r <= 0)
                         return r;
         }
index 0d8d99c56d5c85281d6ee6a3507742060e57db83..8b4af5a2c344b4eddaebf642b7053ffa65df0fb1 100644 (file)
@@ -245,7 +245,7 @@ static int network_link_get_ifindexes(int ifindex, const char *key, int **ret) {
         }
 
         if (ifis)
-                ifis[c] = 0; /* Let's add a 0 ifindex to the end, to be nice*/
+                ifis[c] = 0; /* Let's add a 0 ifindex to the end, to be nice */
 
         *ret = ifis;
         ifis = NULL;
index 4b3cac8a2205533684d985d820f01cfb0a2c4bd8..b709166aa9104f85841618bc8a97243a67f3e9d4 100644 (file)
@@ -1025,7 +1025,7 @@ static int list_devices(void) {
                 j = items + n++;
 
                 for (c = 0; c < _COLUMN_MAX; c++) {
-                        const char *x;
+                        const char *x = NULL;
                         size_t k;
 
                         switch (c) {
index 9d0311d76f9fdcaffe8837179a644178e768ce4d..e34793e50bfa3e0b42e08f7a9e44c1ae2dc083c4 100644 (file)
@@ -85,7 +85,11 @@ int address_new_static(Network *network, const char *filename, unsigned section_
 
         if (filename) {
                 address->section = n;
-                hashmap_put(network->addresses_by_section, n, address);
+                n = NULL;
+
+                r = hashmap_put(network->addresses_by_section, address->section, address);
+                if (r < 0)
+                        return r;
         }
 
         address->network = network;
@@ -94,7 +98,6 @@ int address_new_static(Network *network, const char *filename, unsigned section_
 
         *ret = address;
         address = NULL;
-        n = NULL;
 
         return 0;
 }
index a8ba293ae8ab88ec1ea9ad713bc1421053622ae6..570083f1803b626a017ef900c2bdaf709eab21f5 100644 (file)
@@ -113,7 +113,7 @@ int route_new_static(Network *network, const char *filename, unsigned section_li
                 route->section = n;
                 n = NULL;
 
-                r = hashmap_put(network->routes_by_section, n, route);
+                r = hashmap_put(network->routes_by_section, route->section, route);
                 if (r < 0)
                         return r;
         }
index 5274767b96bf5733f74a6b2153ca5d75287842b9..d749756437c5f867d121ebd5e4c9b5c7389ffdf2 100644 (file)
@@ -78,13 +78,12 @@ int sync_cgroup(pid_t pid, CGroupUnified unified_requested, uid_t arg_uid_shift)
         char tree[] = "/tmp/unifiedXXXXXX", pid_string[DECIMAL_STR_MAX(pid) + 1];
         bool undo_mount = false;
         const char *fn;
-        int unified, r;
+        int r, unified_controller;
 
-        unified = cg_unified(SYSTEMD_CGROUP_CONTROLLER);
-        if (unified < 0)
-                return log_error_errno(unified, "Failed to determine whether the unified hierarchy is used: %m");
-
-        if ((unified > 0) == (unified_requested >= CGROUP_UNIFIED_SYSTEMD))
+        unified_controller = cg_unified_controller(SYSTEMD_CGROUP_CONTROLLER);
+        if (unified_controller < 0)
+                return log_error_errno(unified_controller, "Failed to determine whether the systemd hierarchy is unified: %m");
+        if ((unified_controller > 0) == (unified_requested >= CGROUP_UNIFIED_SYSTEMD))
                 return 0;
 
         /* When the host uses the legacy cgroup setup, but the
@@ -100,7 +99,7 @@ int sync_cgroup(pid_t pid, CGroupUnified unified_requested, uid_t arg_uid_shift)
         if (!mkdtemp(tree))
                 return log_error_errno(errno, "Failed to generate temporary mount point for unified hierarchy: %m");
 
-        if (unified)
+        if (unified_controller > 0)
                 r = mount_verbose(LOG_ERR, "cgroup", tree, "cgroup",
                                   MS_NOSUID|MS_NOEXEC|MS_NODEV, "none,name=systemd,xattr");
         else
@@ -142,7 +141,7 @@ finish:
 int create_subcgroup(pid_t pid, CGroupUnified unified_requested) {
         _cleanup_free_ char *cgroup = NULL;
         const char *child;
-        int unified, r;
+        int r;
         CGroupMask supported;
 
         /* In the unified hierarchy inner nodes may only contain
@@ -154,10 +153,10 @@ int create_subcgroup(pid_t pid, CGroupUnified unified_requested) {
         if (unified_requested == CGROUP_UNIFIED_NONE)
                 return 0;
 
-        unified = cg_unified(SYSTEMD_CGROUP_CONTROLLER);
-        if (unified < 0)
-                return log_error_errno(unified, "Failed to determine whether the unified hierarchy is used: %m");
-        if (unified == 0)
+        r = cg_unified_controller(SYSTEMD_CGROUP_CONTROLLER);
+        if (r < 0)
+                return log_error_errno(r, "Failed to determine whether the systemd controller is unified: %m");
+        if (r == 0)
                 return 0;
 
         r = cg_mask_supported(&supported);
index 4b2838b752c3f906c8bc9d1294379bdf331de1c1..d27699412070ea153ddc13b2bfd781422a06f488 100644 (file)
@@ -545,10 +545,10 @@ int mount_all(const char *dest,
         static const MountPoint mount_table[] = {
                 /* inner child mounts */
                 { "proc",                "/proc",               "proc",  NULL,        MS_NOSUID|MS_NOEXEC|MS_NODEV,                              MOUNT_FATAL|MOUNT_IN_USERNS },
-                { "/proc/sys",           "/proc/sys",           NULL,    NULL,        MS_BIND,                                                   MOUNT_FATAL|MOUNT_IN_USERNS|MOUNT_APPLY_APIVFS_RO },                          /* Bind mount first ...*/
+                { "/proc/sys",           "/proc/sys",           NULL,    NULL,        MS_BIND,                                                   MOUNT_FATAL|MOUNT_IN_USERNS|MOUNT_APPLY_APIVFS_RO },                          /* Bind mount first ... */
                 { "/proc/sys/net",       "/proc/sys/net",       NULL,    NULL,        MS_BIND,                                                   MOUNT_FATAL|MOUNT_IN_USERNS|MOUNT_APPLY_APIVFS_RO|MOUNT_APPLY_APIVFS_NETNS }, /* (except for this) */
                 { NULL,                  "/proc/sys",           NULL,    NULL,        MS_BIND|MS_RDONLY|MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_REMOUNT, MOUNT_FATAL|MOUNT_IN_USERNS|MOUNT_APPLY_APIVFS_RO },                          /* ... then, make it r/o */
-                { "/proc/sysrq-trigger", "/proc/sysrq-trigger", NULL,    NULL,        MS_BIND,                                                               MOUNT_IN_USERNS|MOUNT_APPLY_APIVFS_RO },                          /* Bind mount first ...*/
+                { "/proc/sysrq-trigger", "/proc/sysrq-trigger", NULL,    NULL,        MS_BIND,                                                               MOUNT_IN_USERNS|MOUNT_APPLY_APIVFS_RO },                          /* Bind mount first ... */
                 { NULL,                  "/proc/sysrq-trigger", NULL,    NULL,        MS_BIND|MS_RDONLY|MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_REMOUNT,             MOUNT_IN_USERNS|MOUNT_APPLY_APIVFS_RO },                          /* ... then, make it r/o */
 
                 /* outer child mounts */
@@ -890,7 +890,7 @@ static int get_controllers(Set *subsystems) {
 
                 *e = 0;
 
-                if (STR_IN_SET(l, "", "name=systemd"))
+                if (STR_IN_SET(l, "", "name=systemd", "name=unified"))
                         continue;
 
                 p = strdup(l);
@@ -909,7 +909,6 @@ static int mount_legacy_cgroup_hierarchy(
                 const char *dest,
                 const char *controller,
                 const char *hierarchy,
-                CGroupUnified unified_requested,
                 bool read_only) {
 
         const char *to, *fstype, *opts;
@@ -927,14 +926,12 @@ static int mount_legacy_cgroup_hierarchy(
 
         /* The superblock mount options of the mount point need to be
          * identical to the hosts', and hence writable... */
-        if (streq(controller, SYSTEMD_CGROUP_CONTROLLER)) {
-                if (unified_requested >= CGROUP_UNIFIED_SYSTEMD) {
-                        fstype = "cgroup2";
-                        opts = NULL;
-                } else {
-                        fstype = "cgroup";
-                        opts = "none,name=systemd,xattr";
-                }
+        if (streq(controller, SYSTEMD_CGROUP_CONTROLLER_HYBRID)) {
+                fstype = "cgroup2";
+                opts = NULL;
+        } else if (streq(controller, SYSTEMD_CGROUP_CONTROLLER_LEGACY)) {
+                fstype = "cgroup";
+                opts = "none,name=systemd,xattr";
         } else {
                 fstype = "cgroup";
                 opts = controller;
@@ -994,7 +991,10 @@ static int mount_legacy_cgns_supported(
                         return r;
         }
 
-        if (cg_all_unified() > 0)
+        r = cg_all_unified();
+        if (r < 0)
+                return r;
+        if (r > 0)
                 goto skip_controllers;
 
         controllers = set_new(&string_hash_ops);
@@ -1012,7 +1012,7 @@ static int mount_legacy_cgns_supported(
                 if (!controller)
                         break;
 
-                r = mount_legacy_cgroup_hierarchy("", controller, controller, unified_requested, !userns);
+                r = mount_legacy_cgroup_hierarchy("", controller, controller, !userns);
                 if (r < 0)
                         return r;
 
@@ -1046,7 +1046,13 @@ static int mount_legacy_cgns_supported(
         }
 
 skip_controllers:
-        r = mount_legacy_cgroup_hierarchy("", SYSTEMD_CGROUP_CONTROLLER, "systemd", unified_requested, false);
+        if (unified_requested >= CGROUP_UNIFIED_SYSTEMD) {
+                r = mount_legacy_cgroup_hierarchy("", SYSTEMD_CGROUP_CONTROLLER_HYBRID, "unified", false);
+                if (r < 0)
+                        return r;
+        }
+
+        r = mount_legacy_cgroup_hierarchy("", SYSTEMD_CGROUP_CONTROLLER_LEGACY, "systemd", false);
         if (r < 0)
                 return r;
 
@@ -1091,7 +1097,10 @@ static int mount_legacy_cgns_unsupported(
                         return r;
         }
 
-        if (cg_all_unified() > 0)
+        r = cg_all_unified();
+        if (r < 0)
+                return r;
+        if (r > 0)
                 goto skip_controllers;
 
         controllers = set_new(&string_hash_ops);
@@ -1117,7 +1126,7 @@ static int mount_legacy_cgns_unsupported(
                 if (r == -EINVAL) {
                         /* Not a symbolic link, but directly a single cgroup hierarchy */
 
-                        r = mount_legacy_cgroup_hierarchy(dest, controller, controller, unified_requested, true);
+                        r = mount_legacy_cgroup_hierarchy(dest, controller, controller, true);
                         if (r < 0)
                                 return r;
 
@@ -1137,7 +1146,7 @@ static int mount_legacy_cgns_unsupported(
                                 continue;
                         }
 
-                        r = mount_legacy_cgroup_hierarchy(dest, combined, combined, unified_requested, true);
+                        r = mount_legacy_cgroup_hierarchy(dest, combined, combined, true);
                         if (r < 0)
                                 return r;
 
@@ -1150,7 +1159,13 @@ static int mount_legacy_cgns_unsupported(
         }
 
 skip_controllers:
-        r = mount_legacy_cgroup_hierarchy(dest, SYSTEMD_CGROUP_CONTROLLER, "systemd", unified_requested, false);
+        if (unified_requested >= CGROUP_UNIFIED_SYSTEMD) {
+                r = mount_legacy_cgroup_hierarchy(dest, SYSTEMD_CGROUP_CONTROLLER_HYBRID, "unified", false);
+                if (r < 0)
+                        return r;
+        }
+
+        r = mount_legacy_cgroup_hierarchy(dest, SYSTEMD_CGROUP_CONTROLLER_LEGACY, "systemd", false);
         if (r < 0)
                 return r;
 
@@ -1202,12 +1217,25 @@ int mount_cgroups(
         return mount_legacy_cgns_unsupported(dest, unified_requested, userns, uid_shift, uid_range, selinux_apifs_context);
 }
 
+static int mount_systemd_cgroup_writable_one(const char *systemd_own, const char *systemd_root)
+{
+        int r;
+
+        /* Make our own cgroup a (writable) bind mount */
+        r = mount_verbose(LOG_ERR, systemd_own, systemd_own,  NULL, MS_BIND, NULL);
+        if (r < 0)
+                return r;
+
+        /* And then remount the systemd cgroup root read-only */
+        return mount_verbose(LOG_ERR, NULL, systemd_root, NULL,
+                             MS_BIND|MS_REMOUNT|MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_RDONLY, NULL);
+}
+
 int mount_systemd_cgroup_writable(
                 const char *dest,
                 CGroupUnified unified_requested) {
 
         _cleanup_free_ char *own_cgroup_path = NULL;
-        const char *systemd_root, *systemd_own;
         int r;
 
         assert(dest);
@@ -1220,22 +1248,19 @@ int mount_systemd_cgroup_writable(
         if (path_equal(own_cgroup_path, "/"))
                 return 0;
 
-        if (unified_requested >= CGROUP_UNIFIED_ALL) {
-                systemd_own = strjoina(dest, "/sys/fs/cgroup", own_cgroup_path);
-                systemd_root = prefix_roota(dest, "/sys/fs/cgroup");
-        } else {
-                systemd_own = strjoina(dest, "/sys/fs/cgroup/systemd", own_cgroup_path);
-                systemd_root = prefix_roota(dest, "/sys/fs/cgroup/systemd");
-        }
+        if (unified_requested >= CGROUP_UNIFIED_ALL)
+                return mount_systemd_cgroup_writable_one(strjoina(dest, "/sys/fs/cgroup", own_cgroup_path),
+                                                         prefix_roota(dest, "/sys/fs/cgroup"));
 
-        /* Make our own cgroup a (writable) bind mount */
-        r = mount_verbose(LOG_ERR, systemd_own, systemd_own,  NULL, MS_BIND, NULL);
-        if (r < 0)
-                return r;
+        if (unified_requested >= CGROUP_UNIFIED_SYSTEMD) {
+                r = mount_systemd_cgroup_writable_one(strjoina(dest, "/sys/fs/cgroup/unified", own_cgroup_path),
+                                                      prefix_roota(dest, "/sys/fs/cgroup/unified"));
+                if (r < 0)
+                        return r;
+        }
 
-        /* And then remount the systemd cgroup root read-only */
-        return mount_verbose(LOG_ERR, NULL, systemd_root, NULL,
-                             MS_BIND|MS_REMOUNT|MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_RDONLY, NULL);
+        return mount_systemd_cgroup_writable_one(strjoina(dest, "/sys/fs/cgroup/systemd", own_cgroup_path),
+                                                 prefix_roota(dest, "/sys/fs/cgroup/systemd"));
 }
 
 int setup_volatile_state(
index 751f26272b2ddf71d9be27df23ad643cbcb62b3b..1fc0501c2e70eb590cc8f67ee4d0596486b08813 100644 (file)
@@ -316,7 +316,7 @@ static int custom_mount_check_all(void) {
 
 static int detect_unified_cgroup_hierarchy(const char *directory) {
         const char *e;
-        int r, all_unified, systemd_unified;
+        int r;
 
         /* Allow the user to control whether the unified hierarchy is used */
         e = getenv("UNIFIED_CGROUP_HIERARCHY");
@@ -332,15 +332,11 @@ static int detect_unified_cgroup_hierarchy(const char *directory) {
                 return 0;
         }
 
-        all_unified = cg_all_unified();
-        systemd_unified = cg_unified(SYSTEMD_CGROUP_CONTROLLER);
-
-        if (all_unified < 0 || systemd_unified < 0)
-                return log_error_errno(all_unified < 0 ? all_unified : systemd_unified,
-                                       "Failed to determine whether the unified cgroups hierarchy is used: %m");
-
         /* Otherwise inherit the default from the host system */
-        if (all_unified > 0) {
+        r = cg_all_unified();
+        if (r < 0)
+                return log_error_errno(r, "Failed to determine whether we are in all unified mode.");
+        if (r > 0) {
                 /* Unified cgroup hierarchy support was added in 230. Unfortunately the detection
                  * routine only detects 231, so we'll have a false negative here for 230. */
                 r = systemd_installation_has_version(directory, 230);
@@ -350,9 +346,9 @@ static int detect_unified_cgroup_hierarchy(const char *directory) {
                         arg_unified_cgroup_hierarchy = CGROUP_UNIFIED_ALL;
                 else
                         arg_unified_cgroup_hierarchy = CGROUP_UNIFIED_NONE;
-        } else if (systemd_unified > 0) {
-                /* Mixed cgroup hierarchy support was added in 232 */
-                r = systemd_installation_has_version(directory, 232);
+        } else if (cg_unified_controller(SYSTEMD_CGROUP_CONTROLLER) > 0) {
+                /* Mixed cgroup hierarchy support was added in 233 */
+                r = systemd_installation_has_version(directory, 233);
                 if (r < 0)
                         return log_error_errno(r, "Failed to determine systemd version in container: %m");
                 if (r > 0)
@@ -2168,8 +2164,6 @@ static int inner_child(
         assert(directory);
         assert(kmsg_socket >= 0);
 
-        cg_unified_flush();
-
         if (arg_userns_mode != USER_NAMESPACE_NO) {
                 /* Tell the parent, that it now can write the UID map. */
                 (void) barrier_place(barrier); /* #1 */
@@ -2440,8 +2434,6 @@ static int outer_child(
         assert(notify_socket >= 0);
         assert(kmsg_socket >= 0);
 
-        cg_unified_flush();
-
         if (prctl(PR_SET_PDEATHSIG, SIGKILL) < 0)
                 return log_error_errno(errno, "PR_SET_PDEATHSIG failed: %m");
 
@@ -2486,10 +2478,6 @@ static int outer_child(
         if (r < 0)
                 return r;
 
-        r = detect_unified_cgroup_hierarchy(directory);
-        if (r < 0)
-                return r;
-
         if (arg_userns_mode != USER_NAMESPACE_NO) {
                 /* Let the parent know which UID shift we read from the image */
                 l = send(uid_shift_socket, &arg_uid_shift, sizeof(arg_uid_shift), MSG_NOSIGNAL);
@@ -2554,7 +2542,7 @@ static int outer_child(
          * inside the containter that create a new mount namespace.
          * See https://github.com/systemd/systemd/issues/3860
          * Further submounts (such as /dev) done after this will inherit the
-         * shared propagation mode.*/
+         * shared propagation mode. */
         r = mount_verbose(LOG_ERR, NULL, directory, NULL, MS_SHARED|MS_REC, NULL);
         if (r < 0)
                 return r;
@@ -3542,6 +3530,10 @@ int main(int argc, char *argv[]) {
         log_parse_environment();
         log_open();
 
+        r = cg_unified_flush();
+        if (r < 0)
+                return log_error_errno(r, "Failed to determine whether the unified cgroups hierarchy is used: %m");
+
         /* Make sure rename_process() in the stub init process can work */
         saved_argv = argv;
         saved_argc = argc;
@@ -3810,6 +3802,10 @@ int main(int argc, char *argv[]) {
         if (r < 0)
                 goto finish;
 
+        r = detect_unified_cgroup_hierarchy(arg_directory);
+        if (r < 0)
+                goto finish;
+
         interactive =
                 isatty(STDIN_FILENO) > 0 &&
                 isatty(STDOUT_FILENO) > 0;
index ab85754bf7a939ccc1b6656c65837eda0e97722d..db86b4dcf6f52956350c9c65ec6092d0d3b6b160 100644 (file)
@@ -148,7 +148,7 @@ int dns_answer_add(DnsAnswer *a, DnsResourceRecord *rr, int ifindex, DnsAnswerFl
                          * match. We don't really care if they match
                          * precisely, but we do care whether one is 0
                          * and the other is not. See RFC 2181, Section
-                         * 5.2.*/
+                         * 5.2. */
 
                         if ((rr->ttl == 0) != (a->items[i].rr->ttl == 0))
                                 return -EINVAL;
index 46a25c2bee44831442617818271c533e5fe1420c..f8dab0130815e098159237b6d36f48e891bbf7e5 100644 (file)
@@ -433,7 +433,7 @@ static int dns_cache_put_positive(
                 return 0;
         }
 
-        /* Entry exists already? Update TTL, timestamp and owner*/
+        /* Entry exists already? Update TTL, timestamp and owner */
         existing = dns_cache_get(c, rr);
         if (existing) {
                 dns_cache_item_update_positive(
index ecd70686836b98ceac5d7628cda347fb70ed255b..ff2ad9c1de4fc54b9cd92ad28be839d0d70fb9c1 100644 (file)
@@ -2458,7 +2458,7 @@ static int dns_transaction_requires_nsec(DnsTransaction *t) {
         if (r > 0) {
                 /* The lookup is from a TLD that is proven not to
                  * exist, and we are in downgrade mode, hence ignore
-                 * that fact that we didn't get any NSEC RRs.*/
+                 * that fact that we didn't get any NSEC RRs. */
 
                 log_info("Detected a negative query %s in a private DNS zone, permitting unsigned response.",
                          dns_resource_key_to_string(t->key, key_str, sizeof key_str));
@@ -2763,7 +2763,7 @@ static int dnssec_validate_records(
                         const char *source;
 
                         /* This RRset validated, but as a wildcard. This means we need
-                         * to prove via NSEC/NSEC3 that no matching non-wildcard RR exists.*/
+                         * to prove via NSEC/NSEC3 that no matching non-wildcard RR exists. */
 
                         /* First step, determine the source of synthesis */
                         r = dns_resource_record_source(rrsig, &source);
@@ -2798,7 +2798,7 @@ static int dnssec_validate_records(
                                 return r;
                         if (r == 0) {
                                 /* Data does not require signing. In that case, just copy it over,
-                                 * but remember that this is by no means authenticated.*/
+                                 * but remember that this is by no means authenticated. */
                                 r = dns_answer_move_by_key(validated, &t->answer, rr->key, 0);
                                 if (r < 0)
                                         return r;
index 44c0cd654f47ec9a824acd9d7412b718a3f8771d..3f7f9035cfdcd55af8613cb37bd6b587e628bad2 100644 (file)
@@ -543,7 +543,7 @@ bool link_relevant(Link *l, int family, bool local_multicast) {
          * beat, can do multicast and has at least one link-local (or better) IP address.
          *
          * A link is relevant for non-multicast traffic if it isn't a loopback device, has a link beat, and has at
-         * least one routable address.*/
+         * least one routable address. */
 
         if (l->flags & (IFF_LOOPBACK|IFF_DORMANT))
                 return false;
index 87b520b5409e8768767a999fcaa4ae382d245650..c3106f1ae913d5cbc780a5c82a7bc3e13ce2b250 100644 (file)
@@ -213,7 +213,7 @@ static char *unquote(const char *s, const char* quotes) {
          * trailing quotes if there is one. Doesn't care about
          * escaping or anything.
          *
-         * DON'T USE THIS FOR NEW CODE ANYMORE!*/
+         * DON'T USE THIS FOR NEW CODE ANYMORE! */
 
         l = strlen(s);
         if (l < 2)
index d96ff44e669e3289bae1d34533b34f23be5fe868..32a4c67590e5de1738cb7bdfdb9d46dd5abe04d8 100644 (file)
@@ -636,7 +636,7 @@ int image_clone(Image *i, const char *new_name, bool read_only) {
         case IMAGE_SUBVOLUME:
         case IMAGE_DIRECTORY:
                 /* If we can we'll always try to create a new btrfs subvolume here, even if the source is a plain
-                 * directory.*/
+                 * directory. */
 
                 new_path = strjoina("/var/lib/machines/", new_name);
 
@@ -712,7 +712,7 @@ int image_read_only(Image *i, bool b) {
                    use the "immutable" flag, to at least make the
                    top-level directory read-only. It's not as good as
                    a read-only subvolume, but at least something, and
-                   we can read the value back.*/
+                   we can read the value back. */
 
                 r = chattr_path(i->path, b ? FS_IMMUTABLE_FL : 0, FS_IMMUTABLE_FL);
                 if (r < 0)
index c60fb631fad9923678f0a7b3e07c73fd7619d20a..30cd463722679d78722cc3c6800a19f490b8585a 100644 (file)
 ***/
 
 #include "alloc-util.h"
+#include "build.h"
 #include "cgroup-util.h"
 #include "dirent-util.h"
 #include "fd-util.h"
 #include "format-util.h"
 #include "parse-util.h"
+#include "proc-cmdline.h"
 #include "process-util.h"
 #include "stat-util.h"
 #include "string-util.h"
@@ -332,7 +334,49 @@ static void test_fd_is_cgroup_fs(void) {
         fd = safe_close(fd);
 }
 
+static void test_is_wanted_print(bool header) {
+        _cleanup_free_ char *cmdline = NULL;
+
+        log_info("-- %s --", __func__);
+        assert_se(proc_cmdline(&cmdline) >= 0);
+        log_info("cmdline: %s", cmdline);
+        if (header) {
+
+                log_info(_CGROUP_HIEARCHY_);
+                (void) system("findmnt -n /sys/fs/cgroup");
+        }
+
+        log_info("is_unified_wanted() โ†’ %s", yes_no(cg_is_unified_wanted()));
+        log_info("is_hybrid_wanted() โ†’ %s", yes_no(cg_is_hybrid_wanted()));
+        log_info("is_legacy_wanted() โ†’ %s", yes_no(cg_is_legacy_wanted()));
+        log_info(" ");
+}
+
+static void test_is_wanted(void) {
+        assert_se(setenv("SYSTEMD_PROC_CMDLINE",
+                         "systemd.unified_cgroup_hierarchy", 1) >= 0);
+        test_is_wanted_print(false);
+
+        assert_se(setenv("SYSTEMD_PROC_CMDLINE",
+                         "systemd.unified_cgroup_hierarchy=0", 1) >= 0);
+        test_is_wanted_print(false);
+
+        assert_se(setenv("SYSTEMD_PROC_CMDLINE",
+                         "systemd.unified_cgroup_hierarchy=0 "
+                         "systemd.legacy_systemd_cgroup_controller", 1) >= 0);
+        test_is_wanted_print(false);
+
+        assert_se(setenv("SYSTEMD_PROC_CMDLINE",
+                         "systemd.unified_cgroup_hierarchy=0 "
+                         "systemd.legacy_systemd_cgroup_controller=0", 1) >= 0);
+        test_is_wanted_print(false);
+}
+
 int main(void) {
+        log_set_max_level(LOG_DEBUG);
+        log_parse_environment();
+        log_open();
+
         test_path_decode_unit();
         test_path_get_unit();
         test_path_get_user_unit();
@@ -349,6 +393,9 @@ int main(void) {
         TEST_REQ_RUNNING_SYSTEMD(test_mask_supported());
         TEST_REQ_RUNNING_SYSTEMD(test_is_cgroup_fs());
         TEST_REQ_RUNNING_SYSTEMD(test_fd_is_cgroup_fs());
+        test_is_wanted_print(true);
+        test_is_wanted_print(false); /* run twice to test caching */
+        test_is_wanted();
 
         return 0;
 }
index b4db4a670296d7e6f3cb73479e865ac8da32cc22..a7cd8e4b5131874d62b5535c1afd6d62941d50d9 100644 (file)
@@ -373,16 +373,16 @@ static void test_dns_name_is_valid(void) {
         test_dns_name_is_valid_one("รค", 1);
         test_dns_name_is_valid_one("\n", 0);
 
-        /* 256 characters*/
+        /* 256 characters */
         test_dns_name_is_valid_one("a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345", 0);
 
-        /* 255 characters*/
+        /* 255 characters */
         test_dns_name_is_valid_one("a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a1234", 0);
 
-        /* 254 characters*/
+        /* 254 characters */
         test_dns_name_is_valid_one("a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a123", 0);
 
-        /* 253 characters*/
+        /* 253 characters */
         test_dns_name_is_valid_one("a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12", 1);
 
         /* label of 64 chars length */
index 4f44cf87113505f12fe999b77227991b9ad10a5e..e5cc2a2df85c2bd191b106fe25b6db6e8d0172a4 100644 (file)
@@ -160,8 +160,8 @@ static void test_replace_env(bool braceless) {
         q = replace_env("BARBAR=$BARBAR=${BARBAR}", (char**) env, flags);
         assert_se(streq(q, braceless ? "BARBAR==" : "BARBAR=$BARBAR="));
 
-        q = replace_env("BAR=$BAR$BAR${BAR}${BAR}", (char**) env, flags);
-        assert_se(streq(q, braceless ? "BAR=waldowaldowaldowaldo" : "BAR=$BAR$BARwaldowaldo"));
+        r = replace_env("BAR=$BAR$BAR${BAR}${BAR}", (char**) env, flags);
+        assert_se(streq(r, braceless ? "BAR=waldowaldowaldowaldo" : "BAR=$BAR$BARwaldowaldo"));
 
         p = replace_env("${BAR}$BAR$BAR", (char**) env, flags);
         assert_se(streq(p, braceless ? "waldowaldowaldo" : "waldo$BAR$BAR"));
index 08a138b1b27158826441f3665b7e9c6142e9921c..7326597b8c35eba060a19fc2bab6f07bcfebd8de 100644 (file)
@@ -872,7 +872,7 @@ static int parse_attribute_from_arg(Item *item) {
                 { 's', FS_SECRM_FL },        /* Secure deletion */
                 { 'u', FS_UNRM_FL },         /* Undelete */
                 { 't', FS_NOTAIL_FL },       /* file tail should not be merged */
-                { 'T', FS_TOPDIR_FL },       /* Top of directory hierarchies*/
+                { 'T', FS_TOPDIR_FL },       /* Top of directory hierarchies */
                 { 'C', FS_NOCOW_FL },        /* Do not cow file */
         };