]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
Merge pull request #8993 from keszybz/sd-resolve-coverity-and-related-fixes
authorLennart Poettering <lennart@poettering.net>
Fri, 18 May 2018 18:30:12 +0000 (20:30 +0200)
committerGitHub <noreply@github.com>
Fri, 18 May 2018 18:30:12 +0000 (20:30 +0200)
sd-resolve coverity and related fixes

97 files changed:
README
man/coredump.conf.xml
man/systemd-coredump.xml
man/systemd-inhibit.xml
man/systemd-nspawn.xml
man/systemd.nspawn.xml
man/systemd.service.xml
meson.build
meson_options.txt
rules/60-persistent-storage.rules
shell-completion/bash/timedatectl
src/analyze/analyze-verify.c
src/basic/fd-util.c
src/basic/fs-util.c
src/basic/fs-util.h
src/basic/hashmap.c
src/basic/mempool.c
src/basic/mempool.h
src/basic/parse-util.c
src/basic/parse-util.h
src/basic/path-util.c
src/basic/process-util.c
src/basic/process-util.h
src/basic/rlimit-util.c
src/basic/rlimit-util.h
src/core/all-units.h [new file with mode: 0644]
src/core/automount.h
src/core/cgroup.h
src/core/dbus-cgroup.h
src/core/dbus-execute.c
src/core/dbus-manager.c
src/core/dbus-scope.h
src/core/dbus-unit.c
src/core/dbus.c
src/core/device.h
src/core/dynamic-user.c
src/core/execute.c
src/core/load-fragment-gperf.gperf.m4
src/core/load-fragment.c
src/core/load-fragment.h
src/core/main.c
src/core/manager.c
src/core/manager.h
src/core/mount.c
src/core/mount.h
src/core/org.freedesktop.systemd1.policy.in
src/core/path.h
src/core/scope.h
src/core/service.c
src/core/service.h
src/core/slice.h
src/core/socket.h
src/core/swap.c
src/core/swap.h
src/core/target.h
src/core/timer.h
src/core/unit.c
src/core/unit.h
src/coredump/coredump.c
src/hostname/hostnamed.c
src/journal/lookup3.c
src/journal/test-catalog.c
src/journal/test-compress.c
src/libsystemd-network/test-dhcp-client.c
src/login/inhibit.c
src/login/logind-dbus.c
src/login/logind-seat-dbus.c
src/login/logind-session-dbus.c
src/login/logind-user-dbus.c
src/machine/machine-dbus.c
src/machine/machined-dbus.c
src/nspawn/nspawn-gperf.gperf
src/nspawn/nspawn-settings.c
src/nspawn/nspawn-settings.h
src/nspawn/nspawn.c
src/resolve/resolved-bus.c
src/resolve/resolved-link-bus.c
src/shared/bus-unit-util.c
src/shared/bus-util.c
src/shared/bus-util.h
src/shared/conf-parser.c
src/shared/conf-parser.h
src/sysusers/sysusers.c
src/test/test-conf-parser.c
src/test/test-execute.c
src/test/test-fileio.c
src/test/test-path.c
src/test/test-rlimit-util.c
src/test/test-sched-prio.c
src/test/test-unit-file.c
src/test/test-unit-name.c
src/test/test-watch-pid.c
src/timedate/org.freedesktop.timedate1.policy
src/timedate/timedated.c
src/timesync/timesyncd-bus.c
src/tmpfiles/tmpfiles.c
tmpfiles.d/systemd.conf.m4

diff --git a/README b/README
index 4a561a65cb57382e5bb654942e0dff105be833e3..2cde08c37e1c2ca7c56c7f985af329ec5bd24da6 100644 (file)
--- a/README
+++ b/README
@@ -161,7 +161,7 @@ REQUIREMENTS:
         docbook-xsl (optional, required for documentation)
         xsltproc    (optional, required for documentation)
         python-lxml (optional, required to build the indices)
-        python, meson, ninja
+        python >= 3.4, meson >= 0.44, ninja
         gcc, awk, sed, grep, m4, and similar tools
 
         During runtime, you need the following additional
@@ -303,13 +303,12 @@ WARNINGS:
         For more information on this issue consult
         https://www.freedesktop.org/wiki/Software/systemd/separate-usr-is-broken
 
-        To run systemd under valgrind, compile with VALGRIND defined
-        (e.g. CPPFLAGS='... -DVALGRIND=1' meson <options>) and have valgrind
-        development headers installed (i.e. valgrind-devel or
-        equivalent). Otherwise, false positives will be triggered by code which
-        violates some rules but is actually safe. Note that valgrind generates
-        nice output only on exit(), hence on shutdown we don't execve()
-        systemd-shutdown.
+        To run systemd under valgrind, compile with meson option
+        -Dvalgrind=true and have valgrind development headers installed
+        (i.e. valgrind-devel or equivalent). Otherwise, false positives will be
+        triggered by code which violates some rules but is actually safe. Note
+        that valgrind generates nice output only on exit(), hence on shutdown
+        we don't execve() systemd-shutdown.
 
 STABLE BRANCHES AND BACKPORTS
 
index 048bbc36370af301a3bb05365b38cdfd04d01f02..49debb219a33244befbb72b8d6037f8a8d23b3ad 100644 (file)
@@ -74,7 +74,7 @@
 
         <listitem><para>Controls where to store cores. One of <literal>none</literal>,
         <literal>external</literal>, and <literal>journal</literal>. When
-        <literal>none</literal>, the core dumps will be logged (including the backtrace if
+        <literal>none</literal>, the core dumps may be logged (including the backtrace if
         possible), but not stored permanently. When <literal>external</literal> (the
         default), cores will be stored in <filename>/var/lib/systemd/coredump/</filename>.
         When <literal>journal</literal>, cores will be stored in the journal and rotated
 
         <listitem><para>The maximum size in bytes of a core
         which will be processed. Core dumps exceeding this size
-        will be logged, but the backtrace will not be generated
-        and the core will not be stored.</para></listitem>
+        may be stored, but the backtrace will not be generated.
+        </para>
+
+        <para>Setting <varname>Storage=none</varname> and <varname>ProcessSizeMax=0</varname>
+        disables all coredump handling except for a log entry.</para>
+        </listitem>
       </varlistentry>
 
       <varlistentry>
index 6c3078143f3b23556bb7c02f56a26f9b7940c3bc..6fba19c22352ec1b84f4bce5cd817cf57fd6ace0 100644 (file)
     core dumps and files can be set in files <filename>/etc/systemd/coredump.conf</filename> and snippets mentioned
     above. In addition the storage time of core dump files is restricted by <command>systemd-tmpfiles</command>,
     corresponding settings are by default in <filename>/usr/lib/tmpfiles.d/systemd.conf</filename>.</para>
+
+    <refsect2>
+      <title>Disabling coredump processing</title>
+
+      <para>To disable potentially resource-intensive processing by <command>systemd-coredump</command>,
+      set <programlisting>Storage=none
+ProcessSizeMax=0</programlisting> in
+      <citerefentry><refentrytitle>coredump.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>.
+      </para>
+    </refsect2>
   </refsect1>
 
   <refsect1>
index a3fdcebe2b7bc380103802bc69890b8fd911fb81..6167fb3592e4a17d25a14bf69548a02455b51c3d 100644 (file)
         acquiring one.</para></listitem>
       </varlistentry>
 
+      <xi:include href="standard-options.xml" xpointer="no-pager" />
       <xi:include href="standard-options.xml" xpointer="help" />
       <xi:include href="standard-options.xml" xpointer="version" />
     </variablelist>
     doing so.</para>
   </refsect1>
 
+  <xi:include href="less-variables.xml" />
+
   <refsect1>
     <title>See Also</title>
     <para>
index 1948b0a802bc25b39d3f3403a92dacc52d4f8678..9a0e02187f7abc4a80cbe5b5c977664dcf4b51f1 100644 (file)
         instead.</para></listitem>
       </varlistentry>
 
+      <varlistentry>
+        <term><option>--hostname=</option></term>
+
+        <listitem><para>Controls the hostname to set within the container, if different from the machine name. Expects
+        a valid hostname as argument. If this option is used, the kernel hostname of the container will be set to this
+        value, otherwise it will be initialized to the machine name as controlled by the <option>--machine=</option>
+        option described above. The machine name is used for various aspect of identification of the container from the
+        outside, the kernel hostname configurable with this option is useful for the container to identify itself from
+        the inside. It is usually a good idea to keep both forms of identification synchronized, in order to avoid
+        confusion. It is hence recommended to avoid usage of this option, and use <option>--machine=</option>
+        exclusively. Note that regardless whether the container's hostname is initialized from the name set with
+        <option>--hostname=</option> or the one set with <option>--machine=</option>, the container can later override
+        its kernel hostname freely on its own as well.</para>
+        </listitem>
+      </varlistentry>
+
       <varlistentry>
         <term><option>--uuid=</option></term>
 
         above).</para></listitem>
       </varlistentry>
 
+      <varlistentry>
+        <term><option>--no-new-privileges=</option></term>
+
+        <listitem><para>Takes a boolean argument. Specifies the value of the <constant>PR_SET_NO_NEW_PRIVS</constant>
+        flag for the container payload. Defaults to off. When turned on the payload code of the container cannot
+        acquire new privileges, i.e. the "setuid" file bit as well as file system capabilities will not have an effect
+        anymore. See <citerefentry
+        project='man-pages'><refentrytitle>prctl</refentrytitle><manvolnum>2</manvolnum></citerefentry> for details
+        about this flag. </para></listitem>
+      </varlistentry>
+
       <varlistentry>
         <term><option>--system-call-filter=</option></term>
 
         <listitem><para>Alter the system call filter applied to containers. Takes a space-separated list of system call
         names or group names (the latter prefixed with <literal>@</literal>, as listed by the
-        <command>syscall-filter</command> command of <citerefentry
-        project='man-pages'><refentrytitle>systemd-analyze</refentrytitle><manvolnum>1</manvolnum></citerefentry>). Passed
+        <command>syscall-filter</command> command of
+        <citerefentry><refentrytitle>systemd-analyze</refentrytitle><manvolnum>1</manvolnum></citerefentry>). Passed
         system calls will be permitted. The list may optionally be prefixed by <literal>~</literal>, in which case all
         listed system calls are prohibited. If this command line option is used multiple times the configured lists are
         combined. If both a positive and a negative list (that is one system call list without and one with the
         capabilities are passed using the <command>--capabilities=</command>.</para></listitem>
       </varlistentry>
 
+      <varlistentry>
+        <term><option>--rlimit=</option></term>
+
+        <listitem><para>Sets the specified POSIX resource limit for the container payload. Expects an assignment of the
+        form
+        <literal><replaceable>LIMIT</replaceable>=<replaceable>SOFT</replaceable>:<replaceable>HARD</replaceable></literal>
+        or <literal><replaceable>LIMIT</replaceable>=<replaceable>VALUE</replaceable></literal>, where
+        <replaceable>LIMIT</replaceable> should refer to a resource limit type, such as
+        <constant>RLIMIT_NOFILE</constant> or <constant>RLIMIT_NICE</constant>. The <replaceable>SOFT</replaceable> and
+        <replaceable>HARD</replaceable> fields should refer to the numeric soft and hard resource limit values. If the
+        second form is used, <replaceable>VALUE</replaceable> may specifiy a value that is used both as soft and hard
+        limit. In place of a numeric value the special string <literal>infinity</literal> may be used to turn off
+        resource limiting for the specific type of resource. This command line option may be used multiple times to
+        control limits on multiple limit types. If used multiple times for the same limit type, the last last use
+        wins. For details about resource limits see <citerefentry
+        project='man-pages'><refentrytitle>setrlimit</refentrytitle><manvolnum>2</manvolnum></citerefentry>. By default
+        resource limits for the container's init process (PID 1) are set to the same values the Linux kernel originally
+        passed to the host init system. Note that some resource limits are enforced on resources counted per user, in
+        particular <constant>RLIMIT_NPROC</constant>. This means that unless user namespacing is deployed
+        (i.e. <option>--private-users=</option> is used, see above), any limits set will be applied to the resource
+        usage of the same user on all local containers as well as the host. This means particular care needs to be
+        taken with these limits as they might be triggered by possibly less trusted code. Example:
+        <literal>--rlimit=RLIMIT_NOFILE=8192:16384</literal>.</para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><option>--oom-score-adjust=</option></term>
+
+        <listitem><para>Changes the OOM ("Out Of Memory") score adjustment value for the container payload. This controls
+        <filename>/proc/self/oom_score_adj</filename> which influences the preference with which this container is
+        terminated when memory becomes scarce. For details see <citerefentry
+        project='man-pages'><refentrytitle>proc</refentrytitle><manvolnum>5</manvolnum></citerefentry>. Takes an
+        integer in the range -1000…1000.</para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><option>--cpu-affinity=</option></term>
+
+        <listitem><para>Controls the CPU affinity of the container payload. Takes a comma separated list of CPU numbers
+        or number ranges (the latter's start and end value separated by dashes). See <citerefentry
+        project='man-pages'><refentrytitle>sched_setaffinity</refentrytitle><manvolnum>2</manvolnum></citerefentry> for
+        details.</para></listitem>
+      </varlistentry>
+
       <varlistentry>
         <term><option>--kill-signal=</option></term>
 
-        <listitem><para>Specify the process signal to send to the
-        container's PID 1 when nspawn itself receives SIGTERM, in
-        order to trigger an orderly shutdown of the
-        container. Defaults to SIGRTMIN+3 if <option>--boot</option>
-        is used (on systemd-compatible init systems SIGRTMIN+3
-        triggers an orderly shutdown). For a list of valid signals, see
-        <citerefentry project='man-pages'><refentrytitle>signal</refentrytitle><manvolnum>7</manvolnum></citerefentry>.</para></listitem>
+        <listitem><para>Specify the process signal to send to the container's PID 1 when nspawn itself receives
+        <constant>SIGTERM</constant>, in order to trigger an orderly shutdown of the container. Defaults to
+        <constant>SIGRTMIN+3</constant> if <option>--boot</option> is used (on systemd-compatible init systems
+        <constant>SIGRTMIN+3</constant> triggers an orderly shutdown). If <option>--boot</option> is not used and this
+        option is not specified the container's processes are terminated abrubtly via <constant>SIGKILL</constant>. For
+        a list of valid signals, see <citerefentry
+        project='man-pages'><refentrytitle>signal</refentrytitle><manvolnum>7</manvolnum></citerefentry>.</para></listitem>
       </varlistentry>
 
       <varlistentry>
index b5c60a33e0b0ac2f2b642f80b0bdb7400511e14f..1780bfd79a2277815637ef2a83bed647f3768454 100644 (file)
         all cases.</para></listitem>
       </varlistentry>
 
+      <varlistentry>
+        <term><varname>NoNewPrivileges=</varname></term>
+
+        <listitem><para>Takes a boolean argument that controls the <constant>PR_SET_NO_NEW_PRIVS</constant> flag for
+        the container payload. This is equivalent to the
+        <option>--no-new-privileges=</option> command line switch. See
+        <citerefentry><refentrytitle>systemd-nspawn</refentrytitle><manvolnum>1</manvolnum></citerefentry> for
+        details.</para>
+        </listitem>
+      </varlistentry>
+
       <varlistentry>
         <term><varname>KillSignal=</varname></term>
 
         details.</para></listitem>
       </varlistentry>
 
+      <varlistentry>
+        <term><varname>LimitCPU=</varname></term>
+        <term><varname>LimitFSIZE=</varname></term>
+        <term><varname>LimitDATA=</varname></term>
+        <term><varname>LimitSTACK=</varname></term>
+        <term><varname>LimitCORE=</varname></term>
+        <term><varname>LimitRSS=</varname></term>
+        <term><varname>LimitNOFILE=</varname></term>
+        <term><varname>LimitAS=</varname></term>
+        <term><varname>LimitNPROC=</varname></term>
+        <term><varname>LimitMEMLOCK=</varname></term>
+        <term><varname>LimitLOCKS=</varname></term>
+        <term><varname>LimitSIGPENDING=</varname></term>
+        <term><varname>LimitMSGQUEUE=</varname></term>
+        <term><varname>LimitNICE=</varname></term>
+        <term><varname>LimitRTPRIO=</varname></term>
+        <term><varname>LimitRTTIME=</varname></term>
+
+        <listitem><para>Configures various types of resource limits applied to containers. This is equivalent to the
+        <option>--rlimit=</option> command line switch, and takes the same arguments. See
+        <citerefentry><refentrytitle>systemd-nspawn</refentrytitle><manvolnum>1</manvolnum></citerefentry> for
+        details.</para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><varname>OOMScoreAdjust=</varname></term>
+
+        <listitem><para>Configures the OOM score adjustment value. This is equivalent to the
+        <option>--oom-score-adjust=</option> command line switch, and takes the same argument. See
+        <citerefentry><refentrytitle>systemd-nspawn</refentrytitle><manvolnum>1</manvolnum></citerefentry> for
+        details.</para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><varname>CPUAffinity=</varname></term>
+
+        <listitem><para>Configures the CPU affinity. This is equivalent to the <option>--cpu-affinity=</option> command
+        line switch, and takes the same argument. See
+        <citerefentry><refentrytitle>systemd-nspawn</refentrytitle><manvolnum>1</manvolnum></citerefentry> for
+        details.</para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><varname>Hostname=</varname></term>
+
+        <listitem><para>Configures the kernel hostname set for the container. This is equivalent to the
+        <option>--hostname=</option> command line switch, and takes the same argument. See
+        <citerefentry><refentrytitle>systemd-nspawn</refentrytitle><manvolnum>1</manvolnum></citerefentry> for
+        details.</para></listitem>
+      </varlistentry>
+
     </variablelist>
   </refsect1>
 
index 03c7b01b3bb6861d56226cc0daeaa500b9b73124..e200bef7cbc598a254bed597bf916f2cff1093a5 100644 (file)
         passed to the service manager from a specific service are passed back to the service's main process on the next
         service restart. Any file descriptors passed to the service manager are automatically closed when
         <constant>POLLHUP</constant> or <constant>POLLERR</constant> is seen on them, or when the service is fully
-        stopped and no job is queued or being executed for it.</para></listitem>
+        stopped and no job is queued or being executed for it. If this option is used, <varname>NotifyAccess=</varname>
+        (see above) should be set to open access to the notification socket provided by systemd. If
+        <varname>NotifyAccess=</varname> is not set, it will be implicitly set to
+        <option>main</option>.</para></listitem>
       </varlistentry>
 
       <varlistentry>
index dbe841ba19e22023739134357740a1f4f7f60663..469737819d81dc63fc8b751041813d75e788d876 100644 (file)
@@ -11,7 +11,7 @@ project('systemd', 'c',
                 'sysconfdir=/etc',
                 'localstatedir=/var',
         ],
-        meson_version : '>= 0.41',
+        meson_version : '>= 0.44',
        )
 
 libsystemd_version = '0.22.0'
@@ -291,55 +291,76 @@ if want_ossfuzz
         fuzzing_engine = meson.get_compiler('cpp').find_library('FuzzingEngine')
 endif
 
-foreach arg : ['-Wextra',
-               '-Werror=undef',
-               '-Wlogical-op',
-               '-Wmissing-include-dirs',
-               '-Wold-style-definition',
-               '-Wpointer-arith',
-               '-Winit-self',
-               '-Wdeclaration-after-statement',
-               '-Wfloat-equal',
-               '-Wsuggest-attribute=noreturn',
-               '-Werror=missing-prototypes',
-               '-Werror=implicit-function-declaration',
-               '-Werror=missing-declarations',
-               '-Werror=return-type',
-               '-Werror=incompatible-pointer-types',
-               '-Werror=format=2',
-               '-Wstrict-prototypes',
-               '-Wredundant-decls',
-               '-Wmissing-noreturn',
-               '-Wimplicit-fallthrough=5',
-               '-Wshadow',
-               '-Wendif-labels',
-               '-Wstrict-aliasing=2',
-               '-Wwrite-strings',
-               '-Werror=overflow',
-               '-Wdate-time',
-               '-Wnested-externs',
-               '-ffast-math',
-               '-fno-common',
-               '-fdiagnostics-show-option',
-               '-fno-strict-aliasing',
-               '-fvisibility=hidden',
-               '-fstack-protector',
-               '-fstack-protector-strong',
-               '--param=ssp-buffer-size=4',
-              ]
-        if cc.has_argument(arg)
-                add_project_arguments(arg, language : 'c')
-        endif
-endforeach
+possible_cc_flags = [
+        '-Wextra',
+        '-Werror=undef',
+        '-Wlogical-op',
+        '-Wmissing-include-dirs',
+        '-Wold-style-definition',
+        '-Wpointer-arith',
+        '-Winit-self',
+        '-Wdeclaration-after-statement',
+        '-Wfloat-equal',
+        '-Wsuggest-attribute=noreturn',
+        '-Werror=missing-prototypes',
+        '-Werror=implicit-function-declaration',
+        '-Werror=missing-declarations',
+        '-Werror=return-type',
+        '-Werror=incompatible-pointer-types',
+        '-Werror=format=2',
+        '-Wstrict-prototypes',
+        '-Wredundant-decls',
+        '-Wmissing-noreturn',
+        '-Wimplicit-fallthrough=5',
+        '-Wshadow',
+        '-Wendif-labels',
+        '-Wstrict-aliasing=2',
+        '-Wwrite-strings',
+        '-Werror=overflow',
+        '-Wdate-time',
+        '-Wnested-externs',
+        '-ffast-math',
+        '-fno-common',
+        '-fdiagnostics-show-option',
+        '-fno-strict-aliasing',
+        '-fvisibility=hidden',
+        '-fstack-protector',
+        '-fstack-protector-strong',
+        '--param=ssp-buffer-size=4',
+]
+
+# --as-needed and --no-undefined are provided by meson by default,
+# run mesonconf to see what is enabled
+possible_link_flags = [
+        '-Wl,-z,relro',
+        '-Wl,-z,now',
+]
 
 # the oss-fuzz fuzzers are not built with -fPIE, so don't
 # enable it when we are linking against them
 if not fuzzer_build
-        if cc.has_argument('-fPIE')
-              add_project_arguments('-fPIE', language : 'c')
-        endif
+        possible_cc_flags += '-fPIE'
+        possible_link_flags += '-pie'
+endif
+
+if cc.get_id() == 'clang'
+        possible_cc_flags += [
+                '-Wno-typedef-redefinition',
+                '-Wno-gnu-variable-sized-type-not-at-end',
+        ]
+endif
+
+if get_option('buildtype') != 'debug'
+        possible_cc_flags += [
+                '-ffunction-sections',
+                '-fdata-sections',
+        ]
+
+        possible_link_flags += '-Wl,--gc-sections'
 endif
 
+add_project_arguments(cc.get_supported_arguments(possible_cc_flags), language : 'c')
+
 # "negative" arguments: gcc on purpose does not return an error for "-Wno-"
 # arguments, just emits a warnings. So test for the "positive" version instead.
 foreach arg : ['unused-parameter',
@@ -366,53 +387,18 @@ if cc.compiles('''
         add_project_arguments('-Werror=shadow', language : 'c')
 endif
 
-if cc.get_id() == 'clang'
-        foreach arg : ['-Wno-typedef-redefinition',
-                       '-Wno-gnu-variable-sized-type-not-at-end',
-                      ]
-                if cc.has_argument(arg)
-                        add_project_arguments(arg, language : 'c')
-                endif
-        endforeach
-endif
-
 link_test_c = files('tools/meson-link-test.c')
 
-# --as-needed and --no-undefined are provided by meson by default,
-# run mesonconf to see what is enabled
-foreach arg : ['-Wl,-z,relro',
-               '-Wl,-z,now',
-               '-pie',
-              ]
-
+foreach arg : possible_link_flags
         have = run_command(check_compilation_sh,
                            cc.cmd_array(), '-x', 'c', arg,
                            '-include', link_test_c).returncode() == 0
         message('Linking with @0@ supported: @1@'.format(arg, have ? 'yes' : 'no'))
-        if have and (arg != '-pie' or not fuzzer_build)
+        if have
                 add_project_link_arguments(arg, language : 'c')
         endif
 endforeach
 
-if get_option('buildtype') != 'debug'
-        foreach arg : ['-ffunction-sections',
-                       '-fdata-sections']
-                if cc.has_argument(arg)
-                        add_project_arguments(arg, language : 'c')
-                endif
-        endforeach
-
-        foreach arg : ['-Wl,--gc-sections']
-                have = run_command(check_compilation_sh,
-                                   cc.cmd_array(), '-x', 'c', arg,
-                                   '-include', link_test_c).returncode() == 0
-                message('Linking with @0@ supported: @1@'.format(arg, have ? 'yes' : 'no'))
-                if have
-                        add_project_link_arguments(arg, language : 'c')
-                endif
-        endforeach
-endif
-
 cpp = ' '.join(cc.cmd_array()) + ' -E'
 
 #####################################################################
@@ -694,18 +680,18 @@ getent_result = run_command('getent', 'passwd', '65534')
 if getent_result.returncode() == 0
         name = getent_result.stdout().split(':')[0]
         if name != nobody_user
-                message('WARNING:\n' +
-                        '        The local user with the UID 65534 does not match the configured user name "@0@" of the nobody user (its name is @1@).\n'.format(nobody_user, name) +
-                        '        Your build will result in an user table setup that is incompatible with the local system.')
+                warning('\n' +
+                        'The local user with the UID 65534 does not match the configured user name "@0@" of the nobody user (its name is @1@).\n'.format(nobody_user, name) +
+                        'Your build will result in an user table setup that is incompatible with the local system.')
         endif
 endif
 id_result = run_command('id', '-u', nobody_user)
 if id_result.returncode() == 0
         id = id_result.stdout().to_int()
         if id != 65534
-                message('WARNING:\n' +
-                        '        The local user with the configured user name "@0@" of the nobody user does not have UID 65534 (it has @1@).\n'.format(nobody_user, id) +
-                        '        Your build will result in an user table setup that is incompatible with the local system.')
+                warning('\n' +
+                        'The local user with the configured user name "@0@" of the nobody user does not have UID 65534 (it has @1@).\n'.format(nobody_user, id) +
+                        'Your build will result in an user table setup that is incompatible with the local system.')
         endif
 endif
 
@@ -713,24 +699,24 @@ getent_result = run_command('getent', 'group', '65534')
 if getent_result.returncode() == 0
         name = getent_result.stdout().split(':')[0]
         if name != nobody_group
-                message('WARNING:\n' +
-                        '        The local group with the GID 65534 does not match the configured group name "@0@" of the nobody group (its name is @1@).\n'.format(nobody_group, name) +
-                        '        Your build will result in an group table setup that is incompatible with the local system.')
+                warning('\n' +
+                        'The local group with the GID 65534 does not match the configured group name "@0@" of the nobody group (its name is @1@).\n'.format(nobody_group, name) +
+                        'Your build will result in an group table setup that is incompatible with the local system.')
         endif
 endif
 id_result = run_command('id', '-g', nobody_group)
 if id_result.returncode() == 0
         id = id_result.stdout().to_int()
         if id != 65534
-                message('WARNING:\n' +
-                        '        The local group with the configured group name "@0@" of the nobody group does not have UID 65534 (it has @1@).\n'.format(nobody_group, id) +
-                        '        Your build will result in an group table setup that is incompatible with the local system.')
+                warning('\n' +
+                        'The local group with the configured group name "@0@" of the nobody group does not have UID 65534 (it has @1@).\n'.format(nobody_group, id) +
+                        'Your build will result in an group table setup that is incompatible with the local system.')
         endif
 endif
 if nobody_user != nobody_group and not (nobody_user == 'nobody' and nobody_group == 'nogroup')
-        message('WARNING:\n' +
-                '        The configured user name "@0@" and group name "@0@" of the nobody user/group are not equivalent.\n'.format(nobody_user, nobody_group) +
-                '        Please re-check that both "nobody-user" and "nobody-group" options are correctly set.')
+        warning('\n' +
+                'The configured user name "@0@" and group name "@0@" of the nobody user/group are not equivalent.\n'.format(nobody_user, nobody_group) +
+                'Please re-check that both "nobody-user" and "nobody-group" options are correctly set.')
 endif
 
 conf.set_quoted('NOBODY_USER_NAME', nobody_user)
@@ -774,23 +760,22 @@ conf.set_quoted('GETTEXT_PACKAGE', meson.project_name())
 substs.set('SUSHELL', get_option('debug-shell'))
 substs.set('DEBUGTTY', get_option('debug-tty'))
 
-debug = get_option('debug')
 enable_debug_hashmap = false
 enable_debug_mmap_cache = false
-if debug != ''
-        foreach name : debug.split(',')
-                if name == 'hashmap'
-                        enable_debug_hashmap = true
-                elif name == 'mmap-cache'
-                        enable_debug_mmap_cache = true
-                else
-                        message('unknown debug option "@0@", ignoring'.format(name))
-                endif
-        endforeach
-endif
+foreach name : get_option('debug')
+        if name == 'hashmap'
+                enable_debug_hashmap = true
+        elif name == 'mmap-cache'
+                enable_debug_mmap_cache = true
+        else
+                message('unknown debug option "@0@", ignoring'.format(name))
+        endif
+endforeach
 conf.set10('ENABLE_DEBUG_HASHMAP', enable_debug_hashmap)
 conf.set10('ENABLE_DEBUG_MMAP_CACHE', enable_debug_mmap_cache)
 
+conf.set10('VALGRIND', get_option('valgrind'))
+
 #####################################################################
 
 threads = dependency('threads')
@@ -2942,6 +2927,7 @@ foreach tuple : [
         ['gshadow'],
         ['debug hashmap'],
         ['debug mmap cache'],
+        ['valgrind',         conf.get('VALGRIND') == 1],
 ]
 
         if tuple.length() >= 2
@@ -2967,8 +2953,8 @@ status += [
 message('\n         '.join(status))
 
 if rootprefixdir != rootprefix_default
-        message('WARNING:\n' +
-                '        Note that the installation prefix was changed to "@0@".\n'.format(rootprefixdir) +
-                '        systemd used fixed names for unit file directories and other paths, so anything\n' +
-                '        except the default ("@0@") is strongly discouraged.'.format(rootprefix_default))
+        warning('\n' +
+                'Note that the installation prefix was changed to "@0@".\n'.format(rootprefixdir) +
+                'systemd used fixed names for unit file directories and other paths, so anything\n' +
+                'except the default ("@0@") is strongly discouraged.'.format(rootprefix_default))
 endif
index 61d3381d17c1bb5971b899537c8b78e6b51db75e..e3dea3ebc5413fa9c7e6130f182b1c10ceb13955 100644 (file)
@@ -46,10 +46,12 @@ option('debug-shell', type : 'string', value : '/bin/sh',
        description : 'path to debug shell binary')
 option('debug-tty', type : 'string', value : '/dev/tty9',
        description : 'specify the tty device for debug shell')
-option('debug', type : 'string',
-       description : 'enable extra debugging (hashmap,mmap-cache)')
+option('debug', type : 'array', choices : ['hashmap', 'mmap-cache'], value : [],
+       description : 'enable extra debugging')
 option('memory-accounting-default', type : 'boolean',
        description : 'enable MemoryAccounting= by default')
+option('valgrind', type : 'boolean', value : false,
+       description : 'do extra operations to avoid valgrind warnings')
 
 option('utmp', type : 'boolean',
        description : 'support for utmp/wtmp log handling')
index 0de8cf3a1a404804358496e851523b89c8b6bfe0..8ddb7577c1e63fff164f86db810d906a27d7c542 100644 (file)
@@ -91,7 +91,7 @@ KERNEL!="sr*", IMPORT{builtin}="blkid"
 
 # by-label/by-uuid links (filesystem metadata)
 ENV{ID_FS_USAGE}=="filesystem|other|crypto", ENV{ID_FS_UUID_ENC}=="?*", SYMLINK+="disk/by-uuid/$env{ID_FS_UUID_ENC}"
-ENV{ID_FS_USAGE}=="filesystem|other", ENV{ID_FS_LABEL_ENC}=="?*", SYMLINK+="disk/by-label/$env{ID_FS_LABEL_ENC}"
+ENV{ID_FS_USAGE}=="filesystem|other|crypto", ENV{ID_FS_LABEL_ENC}=="?*", SYMLINK+="disk/by-label/$env{ID_FS_LABEL_ENC}"
 
 # by-id (World Wide Name)
 ENV{DEVTYPE}=="disk", ENV{ID_WWN_WITH_EXTENSION}=="?*", SYMLINK+="disk/by-id/wwn-$env{ID_WWN_WITH_EXTENSION}"
index 13b99f22ba77065ecce95056426b851bf20bd705..417e6d681d295dc71510fb62a345b52a60ccfae1 100644 (file)
@@ -34,7 +34,8 @@ _timedatectl() {
         local i verb comps
         local cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]}
         local OPTS='-h --help --version --adjust-system-clock --no-pager
-                    --no-ask-password -H --host -M --machine'
+                    --no-ask-password -H --host -M --machine --monitor
+                    -p --property -a --all --value'
 
         if __contains_word "$prev" $OPTS; then
                 case $prev in
@@ -56,7 +57,7 @@ _timedatectl() {
 
         local -A VERBS=(
                   [BOOLEAN]='set-local-rtc set-ntp'
-               [STANDALONE]='status list-timezones'
+               [STANDALONE]='status list-timezones timesync-status show-timesync'
                 [TIMEZONES]='set-timezone'
                      [TIME]='set-time'
         )
index 90c10f575a4e604c8baeb975fac6d713fa49588b..694ecc72879de2885c36e31acf2360e3d07b832d 100644 (file)
@@ -8,6 +8,7 @@
 #include <stdlib.h>
 
 #include "alloc-util.h"
+#include "all-units.h"
 #include "analyze-verify.h"
 #include "bus-error.h"
 #include "bus-util.h"
index 4b3e7ed5575f861ff5f47f85749a77343d3c7032..9536a50b740c9d5b6ddd9d72f6bcb1b7d3963fa9 100644 (file)
@@ -199,15 +199,22 @@ int close_all_fds(const int except[], size_t n_except) {
 
         d = opendir("/proc/self/fd");
         if (!d) {
-                int fd;
                 struct rlimit rl;
+                int fd, max_fd;
 
-                /* When /proc isn't available (for example in chroots)
-                 * the fallback is brute forcing through the fd
+                /* When /proc isn't available (for example in chroots) the fallback is brute forcing through the fd
                  * table */
 
                 assert_se(getrlimit(RLIMIT_NOFILE, &rl) >= 0);
-                for (fd = 3; fd < (int) rl.rlim_max; fd ++) {
+
+                if (rl.rlim_max == 0)
+                        return -EINVAL;
+
+                /* Let's take special care if the resource limit is set to unlimited, or actually larger than the range
+                 * of 'int'. Let's avoid implicit overflows. */
+                max_fd = (rl.rlim_max == RLIM_INFINITY || rl.rlim_max > INT_MAX) ? INT_MAX : (int) (rl.rlim_max - 1);
+
+                for (fd = 3; fd >= 0; fd = fd < max_fd ? fd + 1 : -1) {
                         int q;
 
                         if (fd_in_set(fd, except, n_except))
index 232a21c19305cde228d34847a999e1b588d628f1..7d788515cc83171459d22b708005af7fae7102f1 100644 (file)
@@ -1066,6 +1066,15 @@ int access_fd(int fd, int mode) {
         return r;
 }
 
+void unlink_tempfilep(char (*p)[]) {
+        /* If the file is created with mkstemp(), it will (almost always)
+         * change the suffix. Treat this as a sign that the file was
+         * successfully created. We ignore both the rare case where the
+         * original suffix is used and unlink failures. */
+        if (!endswith(*p, ".XXXXXX"))
+                (void) unlink(*p);
+}
+
 int unlinkat_deallocate(int fd, const char *name, int flags) {
         _cleanup_close_ int truncate_fd = -1;
         struct stat st;
index 6157fe81bff1932da3715258e141d7b8d28a5bd6..4923a30074a00cb96b7077fc33305ac9085b09cc 100644 (file)
@@ -104,6 +104,7 @@ DEFINE_TRIVIAL_CLEANUP_FUNC(char*, unlink_and_free);
 
 int access_fd(int fd, int mode);
 
+void unlink_tempfilep(char (*p)[]);
 int unlinkat_deallocate(int fd, const char *name, int flags);
 
 int fsync_directory_of_file(int fd);
index a53d78c417e6bc6d94d8235fa9ed49b4f6d5738c..cf51167c1aa9cea097585c0bd428ae5d4da77e50 100644 (file)
@@ -281,7 +281,7 @@ static const struct hashmap_type_info hashmap_type_info[_HASHMAP_TYPE_MAX] = {
         },
 };
 
-#ifdef VALGRIND
+#if VALGRIND
 __attribute__((destructor)) static void cleanup_pools(void) {
         _cleanup_free_ char *t = NULL;
         int r;
index 4be4a3d38eb4b0f38937d9275812951a3ea37e15..2e55639e829bce475c9cef8313a3cb6761a2af29 100644 (file)
@@ -76,7 +76,7 @@ void mempool_free_tile(struct mempool *mp, void *p) {
         mp->freelist = p;
 }
 
-#ifdef VALGRIND
+#if VALGRIND
 
 void mempool_drop(struct mempool *mp) {
         struct pool *p = mp->first_pool;
index 5322fd480d39668952dd4e6854ecb11fb0bdf1b6..68249cd88118c8011d045db9196938bcb96bb7c1 100644 (file)
@@ -30,6 +30,6 @@ static struct mempool pool_name = { \
 }
 
 
-#ifdef VALGRIND
+#if VALGRIND
 void mempool_drop(struct mempool *mp);
 #endif
index fbb32f3dc58566490d8143b139d6162ed3093a85..07f43b94e5e30db12f2dcd2b6d4cc866db998209 100644 (file)
@@ -676,3 +676,20 @@ int parse_dev(const char *s, dev_t *ret) {
         *ret = d;
         return 0;
 }
+
+int parse_oom_score_adjust(const char *s, int *ret) {
+        int r, v;
+
+        assert(s);
+        assert(ret);
+
+        r = safe_atoi(s, &v);
+        if (r < 0)
+                return r;
+
+        if (v < OOM_SCORE_ADJ_MIN || v > OOM_SCORE_ADJ_MAX)
+                return -ERANGE;
+
+        *ret = v;
+        return 0;
+}
index 742063c9a4057e067860cbd01dcc12b06a023d74..2b75b938c70e3cd22a500be10411807e6b1f6c5c 100644 (file)
@@ -118,3 +118,5 @@ int parse_percent(const char *p);
 int parse_nice(const char *p, int *ret);
 
 int parse_ip_port(const char *s, uint16_t *ret);
+
+int parse_oom_score_adjust(const char *s, int *ret);
index 92897239cc78c22ea445ca941b62a68da96bd7dc..4f428818d167f74a5fe33689ca16e0277c81f931 100644 (file)
@@ -685,11 +685,12 @@ int parse_path_argument_and_warn(const char *path, bool suppress_root, char **ar
                 return log_error_errno(r, "Failed to parse path \"%s\" and make it absolute: %m", path);
 
         path_kill_slashes(p);
-        if (suppress_root && path_equal(p, "/"))
+        if (suppress_root && empty_or_root(p))
                 p = mfree(p);
 
         free(*arg);
         *arg = p;
+
         return 0;
 }
 
index 4180769ee8da3441c07f8f979cb369297c4c7a8f..ce56ce073583a2638c4ee0f73cf6a737e20319f3 100644 (file)
@@ -1445,6 +1445,15 @@ int fork_agent(const char *name, const int except[], size_t n_except, pid_t *ret
         _exit(EXIT_FAILURE);
 }
 
+int set_oom_score_adjust(int value) {
+        char t[DECIMAL_STR_MAX(int)];
+
+        sprintf(t, "%i", value);
+
+        return write_string_file("/proc/self/oom_score_adj", t,
+                                 WRITE_STRING_FILE_VERIFY_ON_FAILURE|WRITE_STRING_FILE_DISABLE_BUFFER);
+}
+
 static const char *const ioprio_class_table[] = {
         [IOPRIO_CLASS_NONE] = "none",
         [IOPRIO_CLASS_RT] = "realtime",
index f8d1b5e3e8f57b41496d7fafc8cf4a25b471e285..0cec7c4c5ca4fbc8ee0dd4b7146c03b90c9aaef7 100644 (file)
@@ -173,6 +173,8 @@ static inline int safe_fork(const char *name, ForkFlags flags, pid_t *ret_pid) {
 
 int fork_agent(const char *name, const int except[], size_t n_except, pid_t *pid, const char *path, ...);
 
+int set_oom_score_adjust(int value);
+
 #if SIZEOF_PID_T == 4
 /* The highest possibly (theoretic) pid_t value on this architecture. */
 #define PID_T_MAX ((pid_t) INT32_MAX)
index d371f0a550a3691aa6444c15dcdfa64a52ad3a2e..57f90474d8f24b57bc708ef7b2ea1e3d0fe6c19d 100644 (file)
@@ -33,6 +33,11 @@ int setrlimit_closest(int resource, const struct rlimit *rlim) {
         if (getrlimit(resource, &highest) < 0)
                 return -errno;
 
+        /* If the hard limit is unbounded anyway, then the EPERM had other reasons, let's propagate the original EPERM
+         * then */
+        if (highest.rlim_max == RLIM_INFINITY)
+                return -EPERM;
+
         fixed.rlim_cur = MIN(rlim->rlim_cur, highest.rlim_max);
         fixed.rlim_max = MIN(rlim->rlim_max, highest.rlim_max);
 
@@ -42,6 +47,32 @@ int setrlimit_closest(int resource, const struct rlimit *rlim) {
         return 0;
 }
 
+int setrlimit_closest_all(const struct rlimit *const *rlim, int *which_failed) {
+        int i, r;
+
+        assert(rlim);
+
+        /* On failure returns the limit's index that failed in *which_failed, but only if non-NULL */
+
+        for (i = 0; i < _RLIMIT_MAX; i++) {
+                if (!rlim[i])
+                        continue;
+
+                r = setrlimit_closest(i, rlim[i]);
+                if (r < 0) {
+                        if (which_failed)
+                                *which_failed = i;
+
+                        return r;
+                }
+        }
+
+        if (which_failed)
+                *which_failed = -1;
+
+        return 0;
+}
+
 static int rlimit_parse_u64(const char *val, rlim_t *ret) {
         uint64_t u;
         int r;
@@ -289,22 +320,48 @@ int rlimit_format(const struct rlimit *rl, char **ret) {
 }
 
 static const char* const rlimit_table[_RLIMIT_MAX] = {
-        [RLIMIT_CPU] = "LimitCPU",
-        [RLIMIT_FSIZE] = "LimitFSIZE",
-        [RLIMIT_DATA] = "LimitDATA",
-        [RLIMIT_STACK] = "LimitSTACK",
-        [RLIMIT_CORE] = "LimitCORE",
-        [RLIMIT_RSS] = "LimitRSS",
-        [RLIMIT_NOFILE] = "LimitNOFILE",
-        [RLIMIT_AS] = "LimitAS",
-        [RLIMIT_NPROC] = "LimitNPROC",
-        [RLIMIT_MEMLOCK] = "LimitMEMLOCK",
-        [RLIMIT_LOCKS] = "LimitLOCKS",
-        [RLIMIT_SIGPENDING] = "LimitSIGPENDING",
-        [RLIMIT_MSGQUEUE] = "LimitMSGQUEUE",
-        [RLIMIT_NICE] = "LimitNICE",
-        [RLIMIT_RTPRIO] = "LimitRTPRIO",
-        [RLIMIT_RTTIME] = "LimitRTTIME"
+        [RLIMIT_AS]         = "AS",
+        [RLIMIT_CORE]       = "CORE",
+        [RLIMIT_CPU]        = "CPU",
+        [RLIMIT_DATA]       = "DATA",
+        [RLIMIT_FSIZE]      = "FSIZE",
+        [RLIMIT_LOCKS]      = "LOCKS",
+        [RLIMIT_MEMLOCK]    = "MEMLOCK",
+        [RLIMIT_MSGQUEUE]   = "MSGQUEUE",
+        [RLIMIT_NICE]       = "NICE",
+        [RLIMIT_NOFILE]     = "NOFILE",
+        [RLIMIT_NPROC]      = "NPROC",
+        [RLIMIT_RSS]        = "RSS",
+        [RLIMIT_RTPRIO]     = "RTPRIO",
+        [RLIMIT_RTTIME]     = "RTTIME",
+        [RLIMIT_SIGPENDING] = "SIGPENDING",
+        [RLIMIT_STACK]      = "STACK",
 };
 
 DEFINE_STRING_TABLE_LOOKUP(rlimit, int);
+
+int rlimit_from_string_harder(const char *s) {
+        const char *suffix;
+
+        /* The official prefix */
+        suffix = startswith(s, "RLIMIT_");
+        if (suffix)
+                return rlimit_from_string(suffix);
+
+        /* Our own unit file setting prefix */
+        suffix = startswith(s, "Limit");
+        if (suffix)
+                return rlimit_from_string(suffix);
+
+        return rlimit_from_string(s);
+}
+
+void rlimit_free_all(struct rlimit **rl) {
+        int i;
+
+        if (!rl)
+                return;
+
+        for (i = 0; i < _RLIMIT_MAX; i++)
+                rl[i] = mfree(rl[i]);
+}
index 3766f78d5854af18c372d6c8ba4fbdfd1f2f57b4..d50fd38c2e2f2de5b0ecbeb4a3296dadd9c48bdf 100644 (file)
 
 const char *rlimit_to_string(int i) _const_;
 int rlimit_from_string(const char *s) _pure_;
+int rlimit_from_string_harder(const char *s) _pure_;
 
 int setrlimit_closest(int resource, const struct rlimit *rlim);
+int setrlimit_closest_all(const struct rlimit * const *rlim, int *which_failed);
 
 int rlimit_parse_one(int resource, const char *val, rlim_t *ret);
 int rlimit_parse(int resource, const char *val, struct rlimit *ret);
 
 int rlimit_format(const struct rlimit *rl, char **ret);
 
+void rlimit_free_all(struct rlimit **rl);
+
 #define RLIMIT_MAKE_CONST(lim) ((struct rlimit) { lim, lim })
diff --git a/src/core/all-units.h b/src/core/all-units.h
new file mode 100644 (file)
index 0000000..ed8350e
--- /dev/null
@@ -0,0 +1,14 @@
+#pragma once
+
+#include "unit.h"
+
+#include "automount.h"
+#include "device.h"
+#include "path.h"
+#include "scope.h"
+#include "service.h"
+#include "slice.h"
+#include "socket.h"
+#include "swap.h"
+#include "target.h"
+#include "timer.h"
index f017b8c7ee7edd8c8fbe434d4429311cc585ed8c..bdadb5547860e3ca1ee0c4c25255f7f7cf9887e0 100644 (file)
@@ -45,3 +45,5 @@ extern const UnitVTable automount_vtable;
 
 const char* automount_result_to_string(AutomountResult i) _const_;
 AutomountResult automount_result_from_string(const char *s) _pure_;
+
+DEFINE_CAST(AUTOMOUNT, Automount);
index b8d1a094674adcdc2fddccd5bc746886e78ffbfa..ef3ee14ad0e1e5dfc4aa7742f4377d46255bbbfc 100644 (file)
@@ -127,7 +127,8 @@ typedef enum CGroupIPAccountingMetric {
         _CGROUP_IP_ACCOUNTING_METRIC_INVALID = -1,
 } CGroupIPAccountingMetric;
 
-#include "unit.h"
+typedef struct Unit Unit;
+typedef struct Manager Manager;
 
 void cgroup_context_init(CGroupContext *c);
 void cgroup_context_done(CGroupContext *c);
index c1c41759e39b38a5e7572d3e0e727dd793e28ea4..b0cd63ebc30b3965ee5bc5aca6be200135f87184 100644 (file)
@@ -9,6 +9,7 @@
 
 #include "sd-bus.h"
 
+#include "unit.h"
 #include "cgroup.h"
 
 extern const sd_bus_vtable bus_cgroup_vtable[];
index 3b1c77e967659e6b3aa1e65e815e0c5d404f13a4..f7e8798327df82c162afa21f0951355845ff7a8e 100644 (file)
@@ -60,6 +60,9 @@ static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_personality, personality, unsig
 static BUS_DEFINE_PROPERTY_GET(property_get_ioprio, "i", ExecContext, exec_context_get_effective_ioprio);
 static BUS_DEFINE_PROPERTY_GET2(property_get_ioprio_class, "i", ExecContext, exec_context_get_effective_ioprio, IOPRIO_PRIO_CLASS);
 static BUS_DEFINE_PROPERTY_GET2(property_get_ioprio_priority, "i", ExecContext, exec_context_get_effective_ioprio, IOPRIO_PRIO_DATA);
+static BUS_DEFINE_PROPERTY_GET_GLOBAL(property_get_empty_string, "s", NULL);
+static BUS_DEFINE_PROPERTY_GET_REF(property_get_syslog_level, "i", int, LOG_PRI);
+static BUS_DEFINE_PROPERTY_GET_REF(property_get_syslog_facility, "i", int, LOG_FAC);
 
 static int property_get_environment_files(
                 sd_bus *bus,
@@ -249,21 +252,6 @@ static int property_get_timer_slack_nsec(
         return sd_bus_message_append(reply, "t", u);
 }
 
-static int property_get_empty_string(
-                sd_bus *bus,
-                const char *path,
-                const char *interface,
-                const char *property,
-                sd_bus_message *reply,
-                void *userdata,
-                sd_bus_error *error) {
-
-        assert(bus);
-        assert(reply);
-
-        return sd_bus_message_append(reply, "s", NULL);
-}
-
 static int property_get_syscall_filter(
                 sd_bus *bus,
                 const char *path,
@@ -508,42 +496,6 @@ static int property_get_working_directory(
         return sd_bus_message_append(reply, "s", wd);
 }
 
-static int property_get_syslog_level(
-                sd_bus *bus,
-                const char *path,
-                const char *interface,
-                const char *property,
-                sd_bus_message *reply,
-                void *userdata,
-                sd_bus_error *error) {
-
-        int *s = userdata;
-
-        assert(bus);
-        assert(reply);
-        assert(s);
-
-        return sd_bus_message_append(reply, "i", LOG_PRI(*s));
-}
-
-static int property_get_syslog_facility(
-                sd_bus *bus,
-                const char *path,
-                const char *interface,
-                const char *property,
-                sd_bus_message *reply,
-                void *userdata,
-                sd_bus_error *error) {
-
-        int *s = userdata;
-
-        assert(bus);
-        assert(reply);
-        assert(s);
-
-        return sd_bus_message_append(reply, "i", LOG_FAC(*s));
-}
-
 static int property_get_stdio_fdname(
                 sd_bus *bus,
                 const char *path,
@@ -1091,8 +1043,8 @@ int bus_exec_context_set_transient_property(
                 UnitWriteFlags flags,
                 sd_bus_error *error) {
 
-        const char *soft = NULL;
-        int r, ri;
+        const char *suffix;
+        int r;
 
         assert(u);
         assert(c);
@@ -2139,8 +2091,14 @@ int bus_exec_context_set_transient_property(
                         return r;
 
                 STRV_FOREACH(p, l) {
-                        if (!path_is_normalized(*p) || path_is_absolute(*p))
-                                return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "%s= path is not valid: %s", name, *p);
+                        if (!path_is_normalized(*p))
+                                return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "%s= path is not normalized: %s", name, *p);
+
+                        if (path_is_absolute(*p))
+                                return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "%s= path is absolute: %s", name, *p);
+
+                        if (path_startswith(*p, "private"))
+                                return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "%s= path can't be 'private': %s", name, *p);
                 }
 
                 if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
@@ -2313,73 +2271,77 @@ int bus_exec_context_set_transient_property(
                 }
 
                 return 1;
-        }
 
-        ri = rlimit_from_string(name);
-        if (ri < 0) {
-                soft = endswith(name, "Soft");
-                if (soft) {
-                        const char *n;
+        } else if ((suffix = startswith(name, "Limit"))) {
+                const char *soft = NULL;
+                int ri;
 
-                        n = strndupa(name, soft - name);
-                        ri = rlimit_from_string(n);
-                        if (ri >= 0)
-                                name = n;
+                ri = rlimit_from_string(suffix);
+                if (ri < 0) {
+                        soft = endswith(suffix, "Soft");
+                        if (soft) {
+                                const char *n;
 
+                                n = strndupa(suffix, soft - suffix);
+                                ri = rlimit_from_string(n);
+                                if (ri >= 0)
+                                        name = strjoina("Limit", n);
+                        }
                 }
-        }
 
-        if (ri >= 0) {
-                uint64_t rl;
-                rlim_t x;
-
-                r = sd_bus_message_read(message, "t", &rl);
-                if (r < 0)
-                        return r;
-
-                if (rl == (uint64_t) -1)
-                        x = RLIM_INFINITY;
-                else {
-                        x = (rlim_t) rl;
-
-                        if ((uint64_t) x != rl)
-                                return -ERANGE;
-                }
+                if (ri >= 0) {
+                        uint64_t rl;
+                        rlim_t x;
 
-                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
-                        _cleanup_free_ char *f = NULL;
-                        struct rlimit nl;
-
-                        if (c->rlimit[ri]) {
-                                nl = *c->rlimit[ri];
-
-                                if (soft)
-                                        nl.rlim_cur = x;
-                                else
-                                        nl.rlim_max = x;
-                        } else
-                                /* When the resource limit is not initialized yet, then assign the value to both fields */
-                                nl = (struct rlimit) {
-                                        .rlim_cur = x,
-                                        .rlim_max = x,
-                                };
-
-                        r = rlimit_format(&nl, &f);
+                        r = sd_bus_message_read(message, "t", &rl);
                         if (r < 0)
                                 return r;
 
-                        if (c->rlimit[ri])
-                                *c->rlimit[ri] = nl;
+                        if (rl == (uint64_t) -1)
+                                x = RLIM_INFINITY;
                         else {
-                                c->rlimit[ri] = newdup(struct rlimit, &nl, 1);
-                                if (!c->rlimit[ri])
-                                        return -ENOMEM;
+                                x = (rlim_t) rl;
+
+                                if ((uint64_t) x != rl)
+                                        return -ERANGE;
                         }
 
-                        unit_write_settingf(u, flags, name, "%s=%s", name, f);
+                        if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
+                                _cleanup_free_ char *f = NULL;
+                                struct rlimit nl;
+
+                                if (c->rlimit[ri]) {
+                                        nl = *c->rlimit[ri];
+
+                                        if (soft)
+                                                nl.rlim_cur = x;
+                                        else
+                                                nl.rlim_max = x;
+                                } else
+                                        /* When the resource limit is not initialized yet, then assign the value to both fields */
+                                        nl = (struct rlimit) {
+                                                .rlim_cur = x,
+                                                .rlim_max = x,
+                                        };
+
+                                r = rlimit_format(&nl, &f);
+                                if (r < 0)
+                                        return r;
+
+                                if (c->rlimit[ri])
+                                        *c->rlimit[ri] = nl;
+                                else {
+                                        c->rlimit[ri] = newdup(struct rlimit, &nl, 1);
+                                        if (!c->rlimit[ri])
+                                                return -ENOMEM;
+                                }
+
+                                unit_write_settingf(u, flags, name, "%s=%s", name, f);
+                        }
+
+                        return 1;
                 }
 
-                return 1;
         }
 
         return 0;
index a618ee04df97af1a9508e85a4fe89e53957eb7ad..4024292ec4876b5f2b821be8afc528be30583578 100644 (file)
@@ -52,6 +52,8 @@ static BUS_DEFINE_PROPERTY_GET_GLOBAL(property_get_architecture, "s", architectu
 static BUS_DEFINE_PROPERTY_GET_GLOBAL(property_get_log_target, "s", log_target_to_string(log_get_target()));
 static BUS_DEFINE_PROPERTY_GET2(property_get_system_state, "s", Manager, manager_state, manager_state_to_string);
 static BUS_DEFINE_PROPERTY_GET_GLOBAL(property_get_timer_slack_nsec, "t", (uint64_t) prctl(PR_GET_TIMERSLACK));
+static BUS_DEFINE_PROPERTY_GET_REF(property_get_hashmap_size, "u", Hashmap *, hashmap_size);
+static BUS_DEFINE_PROPERTY_GET_REF(property_get_set_size, "u", Set *, set_size);
 
 static int property_get_virtualization(
                 sd_bus *bus,
@@ -171,42 +173,6 @@ static int property_set_log_level(
         return r;
 }
 
-static int property_get_hashmap_size(
-                sd_bus *bus,
-                const char *path,
-                const char *interface,
-                const char *property,
-                sd_bus_message *reply,
-                void *userdata,
-                sd_bus_error *error) {
-
-        Hashmap **h = userdata;
-
-        assert(bus);
-        assert(reply);
-        assert(h);
-
-        return sd_bus_message_append(reply, "u", (uint32_t) hashmap_size(*h));
-}
-
-static int property_get_set_size(
-                sd_bus *bus,
-                const char *path,
-                const char *interface,
-                const char *property,
-                sd_bus_message *reply,
-                void *userdata,
-                sd_bus_error *error) {
-
-        Set **s = userdata;
-
-        assert(bus);
-        assert(reply);
-        assert(s);
-
-        return sd_bus_message_append(reply, "u", (uint32_t) set_size(*s));
-}
-
 static int property_get_progress(
                 sd_bus *bus,
                 const char *path,
index f055b70aac8d647e45286bd3dd744df736caa904..115886b134af627c1097eac7210fed1a58dd61a7 100644 (file)
@@ -9,7 +9,7 @@
 
 #include "sd-bus.h"
 
-#include "unit.h"
+#include "scope.h"
 
 extern const sd_bus_vtable bus_scope_vtable[];
 
index 0efba47b1c5f5e34be34314194c8f6e1a8dd0898..14223b122029a7ad952c729d51bce37c01034429 100644 (file)
 #include "user-util.h"
 #include "web-util.h"
 
+static bool unit_can_start_refuse_manual(Unit *u) {
+        return unit_can_start(u) && !u->refuse_manual_start;
+}
+
+static bool unit_can_stop_refuse_manual(Unit *u) {
+        return unit_can_stop(u) && !u->refuse_manual_stop;
+}
+
+static bool unit_can_isolate_refuse_manual(Unit *u) {
+        return unit_can_isolate(u) && !u->refuse_manual_start;
+}
+
 static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_collect_mode, collect_mode, CollectMode);
 static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_load_state, unit_load_state, UnitLoadState);
 static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_job_mode, job_mode, JobMode);
@@ -38,7 +50,11 @@ static BUS_DEFINE_PROPERTY_GET2(property_get_active_state, "s", Unit, unit_activ
 static BUS_DEFINE_PROPERTY_GET(property_get_sub_state, "s", Unit, unit_sub_state_to_string);
 static BUS_DEFINE_PROPERTY_GET2(property_get_unit_file_state, "s", Unit, unit_get_unit_file_state, unit_file_state_to_string);
 static BUS_DEFINE_PROPERTY_GET(property_get_can_reload, "b", Unit, unit_can_reload);
+static BUS_DEFINE_PROPERTY_GET(property_get_can_start, "b", Unit, unit_can_start_refuse_manual);
+static BUS_DEFINE_PROPERTY_GET(property_get_can_stop, "b", Unit, unit_can_stop_refuse_manual);
+static BUS_DEFINE_PROPERTY_GET(property_get_can_isolate, "b", Unit, unit_can_isolate_refuse_manual);
 static BUS_DEFINE_PROPERTY_GET(property_get_need_daemon_reload, "b", Unit, unit_need_daemon_reload);
+static BUS_DEFINE_PROPERTY_GET_GLOBAL(property_get_empty_strv, "as", 0);
 
 static int property_get_names(
                 sd_bus *bus,
@@ -49,20 +65,20 @@ static int property_get_names(
                 void *userdata,
                 sd_bus_error *error) {
 
-        Unit *u = userdata;
+        Set **s = userdata;
         Iterator i;
         const char *t;
         int r;
 
         assert(bus);
         assert(reply);
-        assert(u);
+        assert(s);
 
         r = sd_bus_message_open_container(reply, 'a', "s");
         if (r < 0)
                 return r;
 
-        SET_FOREACH(t, u->names, i) {
+        SET_FOREACH(t, *s, i) {
                 r = sd_bus_message_append(reply, "s", t);
                 if (r < 0)
                         return r;
@@ -122,22 +138,6 @@ static int property_get_dependencies(
         return sd_bus_message_close_container(reply);
 }
 
-static int property_get_obsolete_dependencies(
-                sd_bus *bus,
-                const char *path,
-                const char *interface,
-                const char *property,
-                sd_bus_message *reply,
-                void *userdata,
-                sd_bus_error *error) {
-
-        assert(bus);
-        assert(reply);
-
-        /* For dependency types we don't support anymore always return an empty array */
-        return sd_bus_message_append(reply, "as", 0);
-}
-
 static int property_get_requires_mounts_for(
                 sd_bus *bus,
                 const char *path,
@@ -193,60 +193,6 @@ static int property_get_unit_file_preset(
                                      r > 0 ? "enabled" : "disabled");
 }
 
-static int property_get_can_start(
-                sd_bus *bus,
-                const char *path,
-                const char *interface,
-                const char *property,
-                sd_bus_message *reply,
-                void *userdata,
-                sd_bus_error *error) {
-
-        Unit *u = userdata;
-
-        assert(bus);
-        assert(reply);
-        assert(u);
-
-        return sd_bus_message_append(reply, "b", unit_can_start(u) && !u->refuse_manual_start);
-}
-
-static int property_get_can_stop(
-                sd_bus *bus,
-                const char *path,
-                const char *interface,
-                const char *property,
-                sd_bus_message *reply,
-                void *userdata,
-                sd_bus_error *error) {
-
-        Unit *u = userdata;
-
-        assert(bus);
-        assert(reply);
-        assert(u);
-
-        return sd_bus_message_append(reply, "b", unit_can_stop(u) && !u->refuse_manual_stop);
-}
-
-static int property_get_can_isolate(
-                sd_bus *bus,
-                const char *path,
-                const char *interface,
-                const char *property,
-                sd_bus_message *reply,
-                void *userdata,
-                sd_bus_error *error) {
-
-        Unit *u = userdata;
-
-        assert(bus);
-        assert(reply);
-        assert(u);
-
-        return sd_bus_message_append(reply, "b", unit_can_isolate(u) && !u->refuse_manual_start);
-}
-
 static int property_get_job(
                 sd_bus *bus,
                 const char *path,
@@ -257,20 +203,20 @@ static int property_get_job(
                 sd_bus_error *error) {
 
         _cleanup_free_ char *p = NULL;
-        Unit *u = userdata;
+        Job **j = userdata;
 
         assert(bus);
         assert(reply);
-        assert(u);
+        assert(j);
 
-        if (!u->job)
+        if (!*j)
                 return sd_bus_message_append(reply, "(uo)", 0, "/");
 
-        p = job_dbus_path(u->job);
+        p = job_dbus_path(*j);
         if (!p)
                 return -ENOMEM;
 
-        return sd_bus_message_append(reply, "(uo)", u->job->id, p);
+        return sd_bus_message_append(reply, "(uo)", (*j)->id, p);
 }
 
 static int property_get_conditions(
@@ -325,14 +271,14 @@ static int property_get_load_error(
                 sd_bus_error *error) {
 
         _cleanup_(sd_bus_error_free) sd_bus_error e = SD_BUS_ERROR_NULL;
-        Unit *u = userdata;
+        int *n = userdata;
 
         assert(bus);
         assert(reply);
-        assert(u);
+        assert(n);
 
-        if (u->load_error != 0)
-                sd_bus_error_set_errno(&e, u->load_error);
+        if (*n != 0)
+                sd_bus_error_set_errno(&e, *n);
 
         return sd_bus_message_append(reply, "(ss)", e.name, e.message);
 }
@@ -622,7 +568,7 @@ const sd_bus_vtable bus_unit_vtable[] = {
         SD_BUS_VTABLE_START(0),
 
         SD_BUS_PROPERTY("Id", "s", NULL, offsetof(Unit, id), SD_BUS_VTABLE_PROPERTY_CONST),
-        SD_BUS_PROPERTY("Names", "as", property_get_names, 0, SD_BUS_VTABLE_PROPERTY_CONST),
+        SD_BUS_PROPERTY("Names", "as", property_get_names, offsetof(Unit, names), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("Following", "s", property_get_following, 0, 0),
         SD_BUS_PROPERTY("Requires", "as", property_get_dependencies, offsetof(Unit, dependencies[UNIT_REQUIRES]), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("Requisite", "as", property_get_dependencies, offsetof(Unit, dependencies[UNIT_REQUISITE]), SD_BUS_VTABLE_PROPERTY_CONST),
@@ -664,7 +610,7 @@ const sd_bus_vtable bus_unit_vtable[] = {
         SD_BUS_PROPERTY("CanStop", "b", property_get_can_stop, 0, SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("CanReload", "b", property_get_can_reload, 0, SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("CanIsolate", "b", property_get_can_isolate, 0, SD_BUS_VTABLE_PROPERTY_CONST),
-        SD_BUS_PROPERTY("Job", "(uo)", property_get_job, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
+        SD_BUS_PROPERTY("Job", "(uo)", property_get_job, offsetof(Unit, job), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
         SD_BUS_PROPERTY("StopWhenUnneeded", "b", bus_property_get_bool, offsetof(Unit, stop_when_unneeded), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("RefuseManualStart", "b", bus_property_get_bool, offsetof(Unit, refuse_manual_start), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("RefuseManualStop", "b", bus_property_get_bool, offsetof(Unit, refuse_manual_stop), SD_BUS_VTABLE_PROPERTY_CONST),
@@ -683,7 +629,7 @@ const sd_bus_vtable bus_unit_vtable[] = {
         BUS_PROPERTY_DUAL_TIMESTAMP("AssertTimestamp", offsetof(Unit, assert_timestamp), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
         SD_BUS_PROPERTY("Conditions", "a(sbbsi)", property_get_conditions, offsetof(Unit, conditions), 0),
         SD_BUS_PROPERTY("Asserts", "a(sbbsi)", property_get_conditions, offsetof(Unit, asserts), 0),
-        SD_BUS_PROPERTY("LoadError", "(ss)", property_get_load_error, 0, SD_BUS_VTABLE_PROPERTY_CONST),
+        SD_BUS_PROPERTY("LoadError", "(ss)", property_get_load_error, offsetof(Unit, load_error), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("Transient", "b", bus_property_get_bool, offsetof(Unit, transient), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("Perpetual", "b", bus_property_get_bool, offsetof(Unit, perpetual), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("StartLimitIntervalUSec", "t", bus_property_get_usec, offsetof(Unit, start_limit.interval), SD_BUS_VTABLE_PROPERTY_CONST),
@@ -708,11 +654,12 @@ const sd_bus_vtable bus_unit_vtable[] = {
         SD_BUS_METHOD("Ref", NULL, NULL, bus_unit_method_ref, SD_BUS_VTABLE_UNPRIVILEGED),
         SD_BUS_METHOD("Unref", NULL, NULL, bus_unit_method_unref, SD_BUS_VTABLE_UNPRIVILEGED),
 
-        /* Obsolete properties or obsolete alias names */
-        SD_BUS_PROPERTY("RequiresOverridable", "as", property_get_obsolete_dependencies, 0, SD_BUS_VTABLE_HIDDEN),
-        SD_BUS_PROPERTY("RequisiteOverridable", "as", property_get_obsolete_dependencies, 0, SD_BUS_VTABLE_HIDDEN),
-        SD_BUS_PROPERTY("RequiredByOverridable", "as", property_get_obsolete_dependencies, 0, SD_BUS_VTABLE_HIDDEN),
-        SD_BUS_PROPERTY("RequisiteOfOverridable", "as", property_get_obsolete_dependencies, 0, SD_BUS_VTABLE_HIDDEN),
+        /* For dependency types we don't support anymore always return an empty array */
+        SD_BUS_PROPERTY("RequiresOverridable", "as", property_get_empty_strv, 0, SD_BUS_VTABLE_HIDDEN),
+        SD_BUS_PROPERTY("RequisiteOverridable", "as", property_get_empty_strv, 0, SD_BUS_VTABLE_HIDDEN),
+        SD_BUS_PROPERTY("RequiredByOverridable", "as", property_get_empty_strv, 0, SD_BUS_VTABLE_HIDDEN),
+        SD_BUS_PROPERTY("RequisiteOfOverridable", "as", property_get_empty_strv, 0, SD_BUS_VTABLE_HIDDEN),
+        /* Obsolete alias names */
         SD_BUS_PROPERTY("StartLimitInterval", "t", bus_property_get_usec, offsetof(Unit, start_limit.interval), SD_BUS_VTABLE_PROPERTY_CONST|SD_BUS_VTABLE_HIDDEN),
         SD_BUS_PROPERTY("StartLimitIntervalSec", "t", bus_property_get_usec, offsetof(Unit, start_limit.interval), SD_BUS_VTABLE_PROPERTY_CONST|SD_BUS_VTABLE_HIDDEN),
         SD_BUS_VTABLE_END
index 47492835ee8e729506893717c9a3d02c9042eca0..9e39d8ab7f1a486e2abf5fddcc96b57d76002a61 100644 (file)
@@ -30,6 +30,7 @@
 #include "mkdir.h"
 #include "process-util.h"
 #include "selinux-access.h"
+#include "service.h"
 #include "special.h"
 #include "string-util.h"
 #include "strv.h"
index d52700b66f66bf9ea452018e1d5f351bf7f0fbb6..f188640c59b673b5ad951f73ec6db47c1c7c96f3 100644 (file)
@@ -7,6 +7,8 @@
   Copyright 2010 Lennart Poettering
 ***/
 
+#include "unit.h"
+
 typedef struct Device Device;
 
 typedef enum DeviceFound {
@@ -37,3 +39,5 @@ extern const UnitVTable device_vtable;
 
 int device_found_node(Manager *m, const char *node, bool add, DeviceFound found, bool now);
 bool device_shall_be_bound_by(Unit *device, Unit *u);
+
+DEFINE_CAST(DEVICE, Device);
index 1f4ed576d98a19ade4b8998c2c6a2851e6c0a8b4..05ccc8c854e8a820cc6901c8a1f82248946fc2b7 100644 (file)
@@ -17,6 +17,7 @@
 #include "io-util.h"
 #include "parse-util.h"
 #include "random-util.h"
+#include "socket-util.h"
 #include "stdio-util.h"
 #include "string-util.h"
 #include "user-util.h"
index ecc7e8821a247a8bb653823af15550119f5199c1..9634ef98b10fb02e76ae941f0a9aef2ec37d1f86 100644 (file)
@@ -86,6 +86,7 @@
 #include "selinux-util.h"
 #include "signal-util.h"
 #include "smack-util.h"
+#include "socket-util.h"
 #include "special.h"
 #include "stat-util.h"
 #include "string-table.h"
@@ -2726,7 +2727,7 @@ static int exec_child(
 #endif
         uid_t uid = UID_INVALID;
         gid_t gid = GID_INVALID;
-        int i, r, ngids = 0;
+        int r, ngids = 0;
         size_t n_fds;
         ExecDirectoryType dt;
         int secure_bits;
@@ -2915,15 +2916,9 @@ static int exec_child(
         }
 
         if (context->oom_score_adjust_set) {
-                char t[DECIMAL_STR_MAX(context->oom_score_adjust)];
-
-                /* When we can't make this change due to EPERM, then
-                 * let's silently skip over it. User namespaces
-                 * prohibit write access to this file, and we
-                 * shouldn't trip up over that. */
-
-                sprintf(t, "%i", context->oom_score_adjust);
-                r = write_string_file("/proc/self/oom_score_adj", t, 0);
+                /* When we can't make this change due to EPERM, then let's silently skip over it. User namespaces
+                 * prohibit write access to this file, and we shouldn't trip up over that. */
+                r = set_oom_score_adjust(context->oom_score_adjust);
                 if (IN_SET(r, -EPERM, -EACCES))
                         log_unit_debug_errno(unit, r, "Failed to adjust OOM setting, assuming containerized execution, ignoring: %m");
                 else if (r < 0) {
@@ -3166,17 +3161,12 @@ static int exec_child(
 
         if (needs_sandboxing) {
                 uint64_t bset;
+                int which_failed;
 
-                for (i = 0; i < _RLIMIT_MAX; i++) {
-
-                        if (!context->rlimit[i])
-                                continue;
-
-                        r = setrlimit_closest(i, context->rlimit[i]);
-                        if (r < 0) {
-                                *exit_status = EXIT_LIMITS;
-                                return log_unit_error_errno(unit, r, "Failed to adjust resource limit %s: %m", rlimit_to_string(i));
-                        }
+                r = setrlimit_closest_all((const struct rlimit* const *) context->rlimit, &which_failed);
+                if (r < 0) {
+                        *exit_status = EXIT_LIMITS;
+                        return log_unit_error_errno(unit, r, "Failed to adjust resource limit RLIMIT_%s: %m", rlimit_to_string(which_failed));
                 }
 
                 /* Set the RTPRIO resource limit to 0, but only if nothing else was explicitly requested. */
@@ -3573,8 +3563,7 @@ void exec_context_done(ExecContext *c) {
         c->pass_environment = strv_free(c->pass_environment);
         c->unset_environment = strv_free(c->unset_environment);
 
-        for (l = 0; l < ELEMENTSOF(c->rlimit); l++)
-                c->rlimit[l] = mfree(c->rlimit[l]);
+        rlimit_free_all(c->rlimit);
 
         for (l = 0; l < 3; l++) {
                 c->stdio_fdname[l] = mfree(c->stdio_fdname[l]);
@@ -3974,9 +3963,9 @@ void exec_context_dump(const ExecContext *c, FILE* f, const char *prefix) {
 
         for (i = 0; i < RLIM_NLIMITS; i++)
                 if (c->rlimit[i]) {
-                        fprintf(f, "%s%s: " RLIM_FMT "\n",
+                        fprintf(f, "Limit%s%s: " RLIM_FMT "\n",
                                 prefix, rlimit_to_string(i), c->rlimit[i]->rlim_max);
-                        fprintf(f, "%s%sSoft: " RLIM_FMT "\n",
+                        fprintf(f, "Limit%s%sSoft: " RLIM_FMT "\n",
                                 prefix, rlimit_to_string(i), c->rlimit[i]->rlim_cur);
                 }
 
index 5d90a7c054961c4864c9644a23d21f846b3a777b..3757a651b219c187924fff3b04ff435ebe96b2df 100644 (file)
@@ -6,6 +6,8 @@ _Pragma("GCC diagnostic ignored \"-Wimplicit-fallthrough\"")
 #include "conf-parser.h"
 #include "load-fragment.h"
 #include "missing.h"
+
+#include "all-units.h"
 %}
 struct ConfigPerfItem;
 %null_strings
@@ -80,22 +82,22 @@ $1.RestrictNamespaces,           config_parse_warn_compat,           DISABLED_CO
 $1.RestrictRealtime,             config_parse_warn_compat,           DISABLED_CONFIGURATION,        0
 $1.RestrictAddressFamilies,      config_parse_warn_compat,           DISABLED_CONFIGURATION,        0
 $1.LockPersonality,              config_parse_warn_compat,           DISABLED_CONFIGURATION,        0')
-$1.LimitCPU,                     config_parse_limit,                 RLIMIT_CPU,                    offsetof($1, exec_context.rlimit)
-$1.LimitFSIZE,                   config_parse_limit,                 RLIMIT_FSIZE,                  offsetof($1, exec_context.rlimit)
-$1.LimitDATA,                    config_parse_limit,                 RLIMIT_DATA,                   offsetof($1, exec_context.rlimit)
-$1.LimitSTACK,                   config_parse_limit,                 RLIMIT_STACK,                  offsetof($1, exec_context.rlimit)
-$1.LimitCORE,                    config_parse_limit,                 RLIMIT_CORE,                   offsetof($1, exec_context.rlimit)
-$1.LimitRSS,                     config_parse_limit,                 RLIMIT_RSS,                    offsetof($1, exec_context.rlimit)
-$1.LimitNOFILE,                  config_parse_limit,                 RLIMIT_NOFILE,                 offsetof($1, exec_context.rlimit)
-$1.LimitAS,                      config_parse_limit,                 RLIMIT_AS,                     offsetof($1, exec_context.rlimit)
-$1.LimitNPROC,                   config_parse_limit,                 RLIMIT_NPROC,                  offsetof($1, exec_context.rlimit)
-$1.LimitMEMLOCK,                 config_parse_limit,                 RLIMIT_MEMLOCK,                offsetof($1, exec_context.rlimit)
-$1.LimitLOCKS,                   config_parse_limit,                 RLIMIT_LOCKS,                  offsetof($1, exec_context.rlimit)
-$1.LimitSIGPENDING,              config_parse_limit,                 RLIMIT_SIGPENDING,             offsetof($1, exec_context.rlimit)
-$1.LimitMSGQUEUE,                config_parse_limit,                 RLIMIT_MSGQUEUE,               offsetof($1, exec_context.rlimit)
-$1.LimitNICE,                    config_parse_limit,                 RLIMIT_NICE,                   offsetof($1, exec_context.rlimit)
-$1.LimitRTPRIO,                  config_parse_limit,                 RLIMIT_RTPRIO,                 offsetof($1, exec_context.rlimit)
-$1.LimitRTTIME,                  config_parse_limit,                 RLIMIT_RTTIME,                 offsetof($1, exec_context.rlimit)
+$1.LimitCPU,                     config_parse_rlimit,                RLIMIT_CPU,                    offsetof($1, exec_context.rlimit)
+$1.LimitFSIZE,                   config_parse_rlimit,                RLIMIT_FSIZE,                  offsetof($1, exec_context.rlimit)
+$1.LimitDATA,                    config_parse_rlimit,                RLIMIT_DATA,                   offsetof($1, exec_context.rlimit)
+$1.LimitSTACK,                   config_parse_rlimit,                RLIMIT_STACK,                  offsetof($1, exec_context.rlimit)
+$1.LimitCORE,                    config_parse_rlimit,                RLIMIT_CORE,                   offsetof($1, exec_context.rlimit)
+$1.LimitRSS,                     config_parse_rlimit,                RLIMIT_RSS,                    offsetof($1, exec_context.rlimit)
+$1.LimitNOFILE,                  config_parse_rlimit,                RLIMIT_NOFILE,                 offsetof($1, exec_context.rlimit)
+$1.LimitAS,                      config_parse_rlimit,                RLIMIT_AS,                     offsetof($1, exec_context.rlimit)
+$1.LimitNPROC,                   config_parse_rlimit,                RLIMIT_NPROC,                  offsetof($1, exec_context.rlimit)
+$1.LimitMEMLOCK,                 config_parse_rlimit,                RLIMIT_MEMLOCK,                offsetof($1, exec_context.rlimit)
+$1.LimitLOCKS,                   config_parse_rlimit,                RLIMIT_LOCKS,                  offsetof($1, exec_context.rlimit)
+$1.LimitSIGPENDING,              config_parse_rlimit,                RLIMIT_SIGPENDING,             offsetof($1, exec_context.rlimit)
+$1.LimitMSGQUEUE,                config_parse_rlimit,                RLIMIT_MSGQUEUE,               offsetof($1, exec_context.rlimit)
+$1.LimitNICE,                    config_parse_rlimit,                RLIMIT_NICE,                   offsetof($1, exec_context.rlimit)
+$1.LimitRTPRIO,                  config_parse_rlimit,                RLIMIT_RTPRIO,                 offsetof($1, exec_context.rlimit)
+$1.LimitRTTIME,                  config_parse_rlimit,                RLIMIT_RTTIME,                 offsetof($1, exec_context.rlimit)
 $1.ReadWriteDirectories,         config_parse_namespace_path_strv,   0,                             offsetof($1, exec_context.read_write_paths)
 $1.ReadOnlyDirectories,          config_parse_namespace_path_strv,   0,                             offsetof($1, exec_context.read_only_paths)
 $1.InaccessibleDirectories,      config_parse_namespace_path_strv,   0,                             offsetof($1, exec_context.inaccessible_paths)
index a78039bb4fabc2e2f8881eee63aa4bc71f6d330b..5bc7536287d79a960cdb26bffb14bf85a2d25719 100644 (file)
@@ -20,6 +20,7 @@
 
 #include "af-list.h"
 #include "alloc-util.h"
+#include "all-units.h"
 #include "bus-error.h"
 #include "bus-internal.h"
 #include "bus-util.h"
@@ -44,7 +45,6 @@
 #include "parse-util.h"
 #include "path-util.h"
 #include "process-util.h"
-#include "rlimit-util.h"
 #if HAVE_SECCOMP
 #include "seccomp-util.h"
 #endif
@@ -57,7 +57,6 @@
 #include "strv.h"
 #include "unit-name.h"
 #include "unit-printf.h"
-#include "unit.h"
 #include "user-util.h"
 #include "utf8.h"
 #include "web-util.h"
@@ -366,7 +365,7 @@ int config_parse_socket_listen(const char *unit,
                 p->type = SOCKET_SOCKET;
                 r = unit_full_printf(UNIT(s), rvalue, &k);
                 if (r < 0) {
-                        log_syntax(unit, LOG_ERR, filename, line, r,"Failed to resolve unit specifiers on %s, ignoring: %m", rvalue);
+                        log_syntax(unit, LOG_ERR, filename, line, r, "Failed to resolve unit specifiers on %s, ignoring: %m", rvalue);
                         return 0;
                 }
 
@@ -507,16 +506,17 @@ int config_parse_exec_nice(
         return 0;
 }
 
-int config_parse_exec_oom_score_adjust(const char* unit,
-                                       const char *filename,
-                                       unsigned line,
-                                       const char *section,
-                                       unsigned section_line,
-                                       const char *lvalue,
-                                       int ltype,
-                                       const char *rvalue,
-                                       void *data,
-                                       void *userdata) {
+int config_parse_exec_oom_score_adjust(
+                const char* unit,
+                const char *filename,
+                unsigned line,
+                const char *section,
+                unsigned section_line,
+                const char *lvalue,
+                int ltype,
+                const char *rvalue,
+                void *data,
+                void *userdata) {
 
         ExecContext *c = data;
         int oa, r;
@@ -526,14 +526,18 @@ int config_parse_exec_oom_score_adjust(const char* unit,
         assert(rvalue);
         assert(data);
 
-        r = safe_atoi(rvalue, &oa);
-        if (r < 0) {
-                log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse the OOM score adjust value, ignoring: %s", rvalue);
+        if (isempty(rvalue)) {
+                c->oom_score_adjust_set = false;
                 return 0;
         }
 
-        if (oa < OOM_SCORE_ADJ_MIN || oa > OOM_SCORE_ADJ_MAX) {
-                log_syntax(unit, LOG_ERR, filename, line, 0, "OOM score adjust value out of range, ignoring: %s", rvalue);
+        r = parse_oom_score_adjust(rvalue, &oa);
+        if (r == -ERANGE) {
+                log_syntax(unit, LOG_ERR, filename, line, r, "OOM score adjust value out of range, ignoring: %s", rvalue);
+                return 0;
+        }
+        if (r < 0) {
+                log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse the OOM score adjust value, ignoring: %s", rvalue);
                 return 0;
         }
 
@@ -812,8 +816,7 @@ int config_parse_socket_bindtodevice(
         } else
                 n = NULL;
 
-        free(s->bind_to_device);
-        s->bind_to_device = n;
+        free_and_replace(s->bind_to_device, n);
 
         return 0;
 }
@@ -1370,47 +1373,6 @@ int config_parse_capability_set(
         return 0;
 }
 
-int config_parse_limit(
-                const char *unit,
-                const char *filename,
-                unsigned line,
-                const char *section,
-                unsigned section_line,
-                const char *lvalue,
-                int ltype,
-                const char *rvalue,
-                void *data,
-                void *userdata) {
-
-        struct rlimit **rl = data, d = {};
-        int r;
-
-        assert(filename);
-        assert(lvalue);
-        assert(rvalue);
-        assert(data);
-
-        r = rlimit_parse(ltype, rvalue, &d);
-        if (r == -EILSEQ) {
-                log_syntax(unit, LOG_WARNING, filename, line, r, "Soft resource limit chosen higher than hard limit, ignoring: %s", rvalue);
-                return 0;
-        }
-        if (r < 0) {
-                log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse resource value, ignoring: %s", rvalue);
-                return 0;
-        }
-
-        if (rl[ltype])
-                *rl[ltype] = d;
-        else {
-                rl[ltype] = newdup(struct rlimit, &d, 1);
-                if (!rl[ltype])
-                        return log_oom();
-        }
-
-        return 0;
-}
-
 #if HAVE_SYSV_COMPAT
 int config_parse_sysv_priority(const char *unit,
                                const char *filename,
@@ -3988,9 +3950,21 @@ int config_parse_exec_directories(
                         continue;
                 }
 
-                if (!path_is_normalized(k) || path_is_absolute(k)) {
+                if (!path_is_normalized(k)) {
+                        log_syntax(unit, LOG_ERR, filename, line, 0,
+                                   "%s= path is not normalized, ignoring assignment: %s", lvalue, rvalue);
+                        continue;
+                }
+
+                if (path_is_absolute(k)) {
+                        log_syntax(unit, LOG_ERR, filename, line, 0,
+                                   "%s= path is absolute, ignoring assignment: %s", lvalue, rvalue);
+                        continue;
+                }
+
+                if (path_startswith(k, "private")) {
                         log_syntax(unit, LOG_ERR, filename, line, 0,
-                                   "%s= path is not valid, ignoring assignment: %s", lvalue, rvalue);
+                                   "%s= path can't be 'private', ingoring assignment: %s", lvalue, rvalue);
                         continue;
                 }
 
@@ -4914,7 +4888,7 @@ void unit_dump_config_items(FILE *f) {
                 { config_parse_log_level,             "LEVEL" },
                 { config_parse_exec_secure_bits,      "SECUREBITS" },
                 { config_parse_capability_set,        "BOUNDINGSET" },
-                { config_parse_limit,                 "LIMIT" },
+                { config_parse_rlimit,                "LIMIT" },
                 { config_parse_unit_deps,             "UNIT [...]" },
                 { config_parse_exec,                  "PATH [ARGUMENT [...]]" },
                 { config_parse_service_type,          "SERVICETYPE" },
index 6d9b13ce374e3bf5579f088b18e3a0a14e1bd11d..4af2898b449f597301b7d4f7b25f54c63d2a7c4e 100644 (file)
@@ -43,7 +43,6 @@ int config_parse_exec_cpu_sched_prio(const char *unit, const char *filename, uns
 int config_parse_exec_cpu_affinity(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
 int config_parse_exec_secure_bits(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
 int config_parse_capability_set(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
-int config_parse_limit(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
 int config_parse_sysv_priority(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
 int config_parse_kill_signal(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
 int config_parse_exec_mount_flags(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
index 201882ca95c029277c0bbceb181b4c94315f4319..30dd4a23e86e4e0f99b4b77079f2460d18ff052c 100644 (file)
@@ -40,6 +40,7 @@
 #include "def.h"
 #include "emergency-action.h"
 #include "env-util.h"
+#include "exit-status.h"
 #include "fd-util.h"
 #include "fdset.h"
 #include "fileio.h"
@@ -674,22 +675,22 @@ static int parse_config_file(void) {
                 { "Manager", "DefaultStartLimitIntervalSec",config_parse_sec,            0, &arg_default_start_limit_interval      },
                 { "Manager", "DefaultStartLimitBurst",    config_parse_unsigned,         0, &arg_default_start_limit_burst         },
                 { "Manager", "DefaultEnvironment",        config_parse_environ,          0, &arg_default_environment               },
-                { "Manager", "DefaultLimitCPU",           config_parse_limit,            RLIMIT_CPU, arg_default_rlimit            },
-                { "Manager", "DefaultLimitFSIZE",         config_parse_limit,            RLIMIT_FSIZE, arg_default_rlimit          },
-                { "Manager", "DefaultLimitDATA",          config_parse_limit,            RLIMIT_DATA, arg_default_rlimit           },
-                { "Manager", "DefaultLimitSTACK",         config_parse_limit,            RLIMIT_STACK, arg_default_rlimit          },
-                { "Manager", "DefaultLimitCORE",          config_parse_limit,            RLIMIT_CORE, arg_default_rlimit           },
-                { "Manager", "DefaultLimitRSS",           config_parse_limit,            RLIMIT_RSS, arg_default_rlimit            },
-                { "Manager", "DefaultLimitNOFILE",        config_parse_limit,            RLIMIT_NOFILE, arg_default_rlimit         },
-                { "Manager", "DefaultLimitAS",            config_parse_limit,            RLIMIT_AS, arg_default_rlimit             },
-                { "Manager", "DefaultLimitNPROC",         config_parse_limit,            RLIMIT_NPROC, arg_default_rlimit          },
-                { "Manager", "DefaultLimitMEMLOCK",       config_parse_limit,            RLIMIT_MEMLOCK, arg_default_rlimit        },
-                { "Manager", "DefaultLimitLOCKS",         config_parse_limit,            RLIMIT_LOCKS, arg_default_rlimit          },
-                { "Manager", "DefaultLimitSIGPENDING",    config_parse_limit,            RLIMIT_SIGPENDING, arg_default_rlimit     },
-                { "Manager", "DefaultLimitMSGQUEUE",      config_parse_limit,            RLIMIT_MSGQUEUE, arg_default_rlimit       },
-                { "Manager", "DefaultLimitNICE",          config_parse_limit,            RLIMIT_NICE, arg_default_rlimit           },
-                { "Manager", "DefaultLimitRTPRIO",        config_parse_limit,            RLIMIT_RTPRIO, arg_default_rlimit         },
-                { "Manager", "DefaultLimitRTTIME",        config_parse_limit,            RLIMIT_RTTIME, arg_default_rlimit         },
+                { "Manager", "DefaultLimitCPU",           config_parse_rlimit,           RLIMIT_CPU, arg_default_rlimit            },
+                { "Manager", "DefaultLimitFSIZE",         config_parse_rlimit,           RLIMIT_FSIZE, arg_default_rlimit          },
+                { "Manager", "DefaultLimitDATA",          config_parse_rlimit,           RLIMIT_DATA, arg_default_rlimit           },
+                { "Manager", "DefaultLimitSTACK",         config_parse_rlimit,           RLIMIT_STACK, arg_default_rlimit          },
+                { "Manager", "DefaultLimitCORE",          config_parse_rlimit,           RLIMIT_CORE, arg_default_rlimit           },
+                { "Manager", "DefaultLimitRSS",           config_parse_rlimit,           RLIMIT_RSS, arg_default_rlimit            },
+                { "Manager", "DefaultLimitNOFILE",        config_parse_rlimit,           RLIMIT_NOFILE, arg_default_rlimit         },
+                { "Manager", "DefaultLimitAS",            config_parse_rlimit,           RLIMIT_AS, arg_default_rlimit             },
+                { "Manager", "DefaultLimitNPROC",         config_parse_rlimit,           RLIMIT_NPROC, arg_default_rlimit          },
+                { "Manager", "DefaultLimitMEMLOCK",       config_parse_rlimit,           RLIMIT_MEMLOCK, arg_default_rlimit        },
+                { "Manager", "DefaultLimitLOCKS",         config_parse_rlimit,           RLIMIT_LOCKS, arg_default_rlimit          },
+                { "Manager", "DefaultLimitSIGPENDING",    config_parse_rlimit,           RLIMIT_SIGPENDING, arg_default_rlimit     },
+                { "Manager", "DefaultLimitMSGQUEUE",      config_parse_rlimit,           RLIMIT_MSGQUEUE, arg_default_rlimit       },
+                { "Manager", "DefaultLimitNICE",          config_parse_rlimit,           RLIMIT_NICE, arg_default_rlimit           },
+                { "Manager", "DefaultLimitRTPRIO",        config_parse_rlimit,           RLIMIT_RTPRIO, arg_default_rlimit         },
+                { "Manager", "DefaultLimitRTTIME",        config_parse_rlimit,           RLIMIT_RTTIME, arg_default_rlimit         },
                 { "Manager", "DefaultCPUAccounting",      config_parse_bool,             0, &arg_default_cpu_accounting            },
                 { "Manager", "DefaultIOAccounting",       config_parse_bool,             0, &arg_default_io_accounting             },
                 { "Manager", "DefaultIPAccounting",       config_parse_bool,             0, &arg_default_ip_accounting             },
index 6412fee4764e215e85b6a6841c1a825fe541d1fc..4a2f68b56725c15be4fed7226ce30abe9bfe61be 100644 (file)
@@ -28,6 +28,7 @@
 #include "sd-path.h"
 
 #include "alloc-util.h"
+#include "all-units.h"
 #include "audit-fd.h"
 #include "boot-timestamps.h"
 #include "bus-common-errors.h"
 #include "path-util.h"
 #include "process-util.h"
 #include "ratelimit.h"
+#include "rlimit-util.h"
 #include "rm-rf.h"
 #include "signal-util.h"
+#include "socket-util.h"
 #include "special.h"
 #include "stat-util.h"
 #include "string-table.h"
@@ -1172,7 +1175,6 @@ static void manager_clear_jobs_and_units(Manager *m) {
 
 Manager* manager_free(Manager *m) {
         UnitType c;
-        int i;
         ExecDirectoryType dt;
 
         if (!m)
@@ -1240,8 +1242,7 @@ Manager* manager_free(Manager *m) {
         free(m->switch_root);
         free(m->switch_root_init);
 
-        for (i = 0; i < _RLIMIT_MAX; i++)
-                m->rlimit[i] = mfree(m->rlimit[i]);
+        rlimit_free_all(m->rlimit);
 
         assert(hashmap_isempty(m->units_requiring_mounts_for));
         hashmap_free(m->units_requiring_mounts_for);
index 35a3a1eb4000320573b43085ff03a9f7b128e888..f41cce1c09e99e6583f388431da61962a03f0cf9 100644 (file)
@@ -21,6 +21,7 @@
 #include "ratelimit.h"
 
 struct libmnt_monitor;
+typedef struct Unit Unit;
 
 /* Enforce upper limit how many names we allow */
 #define MANAGER_MAX_NAMES 131072 /* 128K */
index 968ed104dacc3b0bd78a06168191b437638869da..d5463b76213b33cbda9bf357deffbdeda8c87e98 100644 (file)
@@ -16,6 +16,7 @@
 
 #include "alloc-util.h"
 #include "dbus-mount.h"
+#include "device.h"
 #include "escape.h"
 #include "exit-status.h"
 #include "format-util.h"
index 08a4cfe61f1daa6748a965bc4ba1750696adb144..71dac128c22237372032662d6eecb6066a1dc4e3 100644 (file)
@@ -11,6 +11,7 @@ typedef struct Mount Mount;
 
 #include "kill.h"
 #include "dynamic-user.h"
+#include "unit.h"
 
 typedef enum MountExecCommand {
         MOUNT_EXEC_MOUNT,
@@ -97,3 +98,5 @@ MountExecCommand mount_exec_command_from_string(const char *s) _pure_;
 
 const char* mount_result_to_string(MountResult i) _const_;
 MountResult mount_result_from_string(const char *s) _pure_;
+
+DEFINE_CAST(MOUNT, Mount);
index 648221b85cb8a9d6de0b0d34fd964a767a78af6a..001408d34ae3ec13180632e68868bf70396695cc 100644 (file)
@@ -47,6 +47,7 @@
                         <allow_inactive>auth_admin</allow_inactive>
                         <allow_active>auth_admin_keep</allow_active>
                 </defaults>
+                <annotate key="org.freedesktop.policykit.imply">org.freedesktop.systemd1.reload-daemon org.freedesktop.systemd1.manage-units</annotate>
         </action>
 
         <action id="org.freedesktop.systemd1.set-environment">
index ca7dac227d969fb4ebbfe9af2aa2a9de912603f8..2aa2ca111f055c799f9dfc9065670507fcc072f5 100644 (file)
@@ -79,3 +79,5 @@ PathType path_type_from_string(const char *s) _pure_;
 
 const char* path_result_to_string(PathResult i) _const_;
 PathResult path_result_from_string(const char *s) _pure_;
+
+DEFINE_CAST(PATH, Path);
index 6e314eeda3af1da2bf99fe269a1cc6a032917242..e74014119d77936df2813a274aaaa3b48a014e36 100644 (file)
@@ -46,3 +46,5 @@ int scope_abandon(Scope *s);
 
 const char* scope_result_to_string(ScopeResult i) _const_;
 ScopeResult scope_result_from_string(const char *s) _pure_;
+
+DEFINE_CAST(SCOPE, Scope);
index bf4f27880d1fd960ebebd12b9b4d0de1c0fa6c58..1af30325976f3576a2b2a3282e016f8ed551f0ec 100644 (file)
@@ -715,10 +715,9 @@ static int service_add_extras(Service *s) {
         if (r < 0)
                 return r;
 
-        if (s->type == SERVICE_NOTIFY && s->notify_access == NOTIFY_NONE)
-                s->notify_access = NOTIFY_MAIN;
-
-        if (s->watchdog_usec > 0 && s->notify_access == NOTIFY_NONE)
+        /* If the service needs the notify socket, let's enable it automatically. */
+        if (s->notify_access == NOTIFY_NONE &&
+            (s->type == SERVICE_NOTIFY || s->watchdog_usec > 0 || s->n_fd_store_max > 0))
                 s->notify_access = NOTIFY_MAIN;
 
         r = service_add_default_dependencies(s);
index 116d5d119fabb279796e61f514923205dcdc9a6b..6d64f8e9e6fe98efb4dd249fcdaad3a4f30be640 100644 (file)
@@ -14,6 +14,8 @@ typedef struct ServiceFDStore ServiceFDStore;
 #include "kill.h"
 #include "path.h"
 #include "ratelimit.h"
+#include "socket.h"
+#include "unit.h"
 
 typedef enum ServiceRestart {
         SERVICE_RESTART_NO,
@@ -204,3 +206,5 @@ NotifyState notify_state_from_string(const char *s) _pure_;
 
 const char* service_result_to_string(ServiceResult i) _const_;
 ServiceResult service_result_from_string(const char *s) _pure_;
+
+DEFINE_CAST(SERVICE, Service);
index 7d48fafa3aca364674b980aac97870f7a5e0cdae..0ab479467ce877254c50f974ca974cd95f0acab7 100644 (file)
@@ -7,6 +7,8 @@
   Copyright 2013 Lennart Poettering
 ***/
 
+#include "unit.h"
+
 typedef struct Slice Slice;
 
 struct Slice {
@@ -18,3 +20,5 @@ struct Slice {
 };
 
 extern const UnitVTable slice_vtable;
+
+DEFINE_CAST(SLICE, Slice);
index ce9452dbd6904f8d3a8ffbdd3eb9d5ec8aca6110..8a9559d5c6da0c7f89a92338a134491e96a3c3d3 100644 (file)
@@ -13,6 +13,7 @@ typedef struct SocketPeer SocketPeer;
 #include "mount.h"
 #include "service.h"
 #include "socket-util.h"
+#include "unit.h"
 
 typedef enum SocketExecCommand {
         SOCKET_EXEC_START_PRE,
@@ -182,3 +183,5 @@ SocketResult socket_result_from_string(const char *s) _pure_;
 
 const char* socket_port_type_to_string(SocketPort *p) _pure_;
 SocketType socket_port_type_from_string(const char *p) _pure_;
+
+DEFINE_CAST(SOCKET, Socket);
index 618a8d553dc258e5b4687360e939dfdffb8ed38f..e75c9f2464f01cc91ebecee5387aca861457ec86 100644 (file)
@@ -14,6 +14,7 @@
 
 #include "alloc-util.h"
 #include "dbus-swap.h"
+#include "device.h"
 #include "escape.h"
 #include "exit-status.h"
 #include "fd-util.h"
index ec29ccfa6e2aa011723865967fdf6e454d720d8c..fdb14e667a3e3a3e37cb221787115e133517178a 100644 (file)
@@ -9,6 +9,7 @@
 ***/
 
 #include "libudev.h"
+#include "unit.h"
 
 typedef struct Swap Swap;
 
@@ -95,3 +96,5 @@ SwapExecCommand swap_exec_command_from_string(const char *s) _pure_;
 
 const char* swap_result_to_string(SwapResult i) _const_;
 SwapResult swap_result_from_string(const char *s) _pure_;
+
+DEFINE_CAST(SWAP, Swap);
index 2b099c2513a36b06316ced0eae88f7102c4b346b..4a2dea17ed63ff11f6088cd1a6b0c2cf42045c52 100644 (file)
@@ -1,6 +1,8 @@
 /* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
+#include "unit.h"
+
 /***
   This file is part of systemd.
 
@@ -16,3 +18,5 @@ struct Target {
 };
 
 extern const UnitVTable target_vtable;
+
+DEFINE_CAST(TARGET, Target);
index 728afba9bda0d481303de48696cdf3a1fc547f3b..0588a96ca2445d7d6b886cb7a9570ef895439fef 100644 (file)
@@ -10,6 +10,7 @@
 typedef struct Timer Timer;
 
 #include "calendarspec.h"
+#include "unit.h"
 
 typedef enum TimerBase {
         TIMER_ACTIVE,
@@ -77,3 +78,5 @@ TimerBase timer_base_from_string(const char *s) _pure_;
 
 const char* timer_result_to_string(TimerResult i) _const_;
 TimerResult timer_result_from_string(const char *s) _pure_;
+
+DEFINE_CAST(TIMER, Timer);
index 13e00a25c8233f49190f1ffd17071385fe46ae14..c7320240f7bdebc76d0da973f9736d47327e32ce 100644 (file)
@@ -16,6 +16,7 @@
 #include "sd-messages.h"
 
 #include "alloc-util.h"
+#include "all-units.h"
 #include "bus-common-errors.h"
 #include "bus-util.h"
 #include "cgroup-util.h"
index 26194ef35a0a90eab44a7a999da8ed16aa3974ce..767cd96aeb6de4f1e7f4b1f74172c052b9116928 100644 (file)
 #include <stdlib.h>
 #include <unistd.h>
 
-typedef struct Unit Unit;
-typedef struct UnitVTable UnitVTable;
-typedef struct UnitRef UnitRef;
-typedef struct UnitStatusMessageFormats UnitStatusMessageFormats;
-
 #include "bpf-program.h"
 #include "condition.h"
 #include "emergency-action.h"
@@ -24,6 +19,8 @@ typedef struct UnitStatusMessageFormats UnitStatusMessageFormats;
 #include "unit-name.h"
 #include "cgroup.h"
 
+typedef struct UnitRef UnitRef;
+
 typedef enum KillOperation {
         KILL_TERMINATE,
         KILL_TERMINATE_AND_LOG,
@@ -120,7 +117,7 @@ typedef enum UnitCGroupBPFState {
         UNIT_CGROUP_BPF_INVALIDATED = -1,
 } UnitCGroupBPFState;
 
-struct Unit {
+typedef struct Unit {
         Manager *manager;
 
         UnitType type;
@@ -358,13 +355,13 @@ struct Unit {
         /* When writing transient unit files, stores which section we stored last. If < 0, we didn't write any yet. If
          * == 0 we are in the [Unit] section, if > 0 we are in the unit type-specific section. */
         int last_section_private:2;
-};
+} Unit;
 
-struct UnitStatusMessageFormats {
+typedef struct UnitStatusMessageFormats {
         const char *starting_stopping[2];
         const char *finished_start_job[_JOB_RESULT_MAX];
         const char *finished_stop_job[_JOB_RESULT_MAX];
-};
+} UnitStatusMessageFormats;
 
 /* Flags used when writing drop-in files or transient unit files */
 typedef enum UnitWriteFlags {
@@ -387,17 +384,9 @@ typedef enum UnitWriteFlags {
 /* Returns true if neither persistent, nor runtime storage is requested, i.e. this is a check invocation only */
 #define UNIT_WRITE_FLAGS_NOOP(flags) (((flags) & (UNIT_RUNTIME|UNIT_PERSISTENT)) == 0)
 
-#include "automount.h"
-#include "device.h"
-#include "path.h"
-#include "scope.h"
-#include "slice.h"
-#include "socket.h"
-#include "swap.h"
-#include "target.h"
-#include "timer.h"
-
-struct UnitVTable {
+#include "kill.h"
+
+typedef struct UnitVTable {
         /* How much memory does an object of this unit type need */
         size_t object_size;
 
@@ -566,7 +555,7 @@ struct UnitVTable {
 
         /* True if queued jobs of this type should be GC'ed if no other job needs them anymore */
         bool gc_jobs:1;
-};
+} UnitVTable;
 
 extern const UnitVTable * const unit_vtable[_UNIT_TYPE_MAX];
 
@@ -590,18 +579,6 @@ extern const UnitVTable * const unit_vtable[_UNIT_TYPE_MAX];
 
 #define UNIT_TRIGGER(u) ((Unit*) hashmap_first_key((u)->dependencies[UNIT_TRIGGERS]))
 
-DEFINE_CAST(SERVICE, Service);
-DEFINE_CAST(SOCKET, Socket);
-DEFINE_CAST(TARGET, Target);
-DEFINE_CAST(DEVICE, Device);
-DEFINE_CAST(MOUNT, Mount);
-DEFINE_CAST(AUTOMOUNT, Automount);
-DEFINE_CAST(SWAP, Swap);
-DEFINE_CAST(TIMER, Timer);
-DEFINE_CAST(PATH, Path);
-DEFINE_CAST(SLICE, Slice);
-DEFINE_CAST(SCOPE, Scope);
-
 Unit *unit_new(Manager *m, size_t size);
 void unit_free(Unit *u);
 DEFINE_TRIVIAL_CLEANUP_FUNC(Unit *, unit_free);
index 423a1c21a415c107cf634ca772b305e6627939ad..c1f396b1ac762ee64c61f8498b71292ced8dfc44 100644 (file)
@@ -141,7 +141,12 @@ static int parse_config(void) {
 }
 
 static inline uint64_t storage_size_max(void) {
-        return arg_storage == COREDUMP_STORAGE_EXTERNAL ? arg_external_size_max : arg_journal_size_max;
+        if (arg_storage == COREDUMP_STORAGE_EXTERNAL)
+                return arg_external_size_max;
+        if (arg_storage == COREDUMP_STORAGE_JOURNAL)
+                return arg_journal_size_max;
+        assert(arg_storage == COREDUMP_STORAGE_NONE);
+        return 0;
 }
 
 static int fix_acl(int fd, uid_t uid) {
@@ -323,7 +328,7 @@ static int save_external_coredump(
 
         _cleanup_free_ char *fn = NULL, *tmp = NULL;
         _cleanup_close_ int fd = -1;
-        uint64_t rlimit, max_size;
+        uint64_t rlimit, process_limit, max_size;
         struct stat st;
         uid_t uid;
         int r;
@@ -350,8 +355,14 @@ static int save_external_coredump(
                 return -EBADSLT;
         }
 
+        process_limit = MAX(arg_process_size_max, storage_size_max());
+        if (process_limit == 0) {
+                log_debug("Limits for coredump processing and storage are both 0, not dumping core.");
+                return -EBADSLT;
+        }
+
         /* Never store more than the process configured, or than we actually shall keep or process */
-        max_size = MIN(rlimit, MAX(arg_process_size_max, storage_size_max()));
+        max_size = MIN(rlimit, process_limit);
 
         r = make_filename(context, &fn);
         if (r < 0)
index f3deece5b0b15ff6a8e288efb83cdf107660acee..88a8938c311d7d670c342698caac1ede5dcbd9b0 100644 (file)
@@ -399,7 +399,6 @@ static int method_set_hostname(sd_bus_message *m, void *userdata, sd_bus_error *
         Context *c = userdata;
         const char *name;
         int interactive;
-        char *h;
         int r;
 
         assert(m);
@@ -435,12 +434,9 @@ static int method_set_hostname(sd_bus_message *m, void *userdata, sd_bus_error *
         if (r == 0)
                 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
 
-        h = strdup(name);
-        if (!h)
-                return -ENOMEM;
-
-        free(c->data[PROP_HOSTNAME]);
-        c->data[PROP_HOSTNAME] = h;
+        r = free_and_strdup(&c->data[PROP_HOSTNAME], name);
+        if (r < 0)
+                return r;
 
         r = context_update_kernel_hostname(c);
         if (r < 0) {
@@ -473,6 +469,9 @@ static int method_set_static_hostname(sd_bus_message *m, void *userdata, sd_bus_
         if (streq_ptr(name, c->data[PROP_STATIC_HOSTNAME]))
                 return sd_bus_reply_method_return(m, NULL);
 
+        if (!isempty(name) && !hostname_is_valid(name, false))
+                return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid static hostname '%s'", name);
+
         r = bus_verify_polkit_async(
                         m,
                         CAP_SYS_ADMIN,
@@ -487,21 +486,9 @@ static int method_set_static_hostname(sd_bus_message *m, void *userdata, sd_bus_
         if (r == 0)
                 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
 
-        if (isempty(name))
-                c->data[PROP_STATIC_HOSTNAME] = mfree(c->data[PROP_STATIC_HOSTNAME]);
-        else {
-                char *h;
-
-                if (!hostname_is_valid(name, false))
-                        return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid static hostname '%s'", name);
-
-                h = strdup(name);
-                if (!h)
-                        return -ENOMEM;
-
-                free(c->data[PROP_STATIC_HOSTNAME]);
-                c->data[PROP_STATIC_HOSTNAME] = h;
-        }
+        r = free_and_strdup(&c->data[PROP_STATIC_HOSTNAME], name);
+        if (r < 0)
+                return r;
 
         r = context_update_kernel_hostname(c);
         if (r < 0) {
@@ -539,6 +526,22 @@ static int set_machine_info(Context *c, sd_bus_message *m, int prop, sd_bus_mess
         if (streq_ptr(name, c->data[prop]))
                 return sd_bus_reply_method_return(m, NULL);
 
+        if (!isempty(name)) {
+                /* The icon name might ultimately be used as file
+                 * name, so better be safe than sorry */
+
+                if (prop == PROP_ICON_NAME && !filename_is_valid(name))
+                        return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid icon name '%s'", name);
+                if (prop == PROP_PRETTY_HOSTNAME && string_has_cc(name, NULL))
+                        return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid pretty host name '%s'", name);
+                if (prop == PROP_CHASSIS && !valid_chassis(name))
+                        return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid chassis '%s'", name);
+                if (prop == PROP_DEPLOYMENT && !valid_deployment(name))
+                        return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid deployment '%s'", name);
+                if (prop == PROP_LOCATION && string_has_cc(name, NULL))
+                        return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid location '%s'", name);
+        }
+
         /* Since the pretty hostname should always be changed at the
          * same time as the static one, use the same policy action for
          * both... */
@@ -557,32 +560,9 @@ static int set_machine_info(Context *c, sd_bus_message *m, int prop, sd_bus_mess
         if (r == 0)
                 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
 
-        if (isempty(name))
-                c->data[prop] = mfree(c->data[prop]);
-        else {
-                char *h;
-
-                /* The icon name might ultimately be used as file
-                 * name, so better be safe than sorry */
-
-                if (prop == PROP_ICON_NAME && !filename_is_valid(name))
-                        return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid icon name '%s'", name);
-                if (prop == PROP_PRETTY_HOSTNAME && string_has_cc(name, NULL))
-                        return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid pretty host name '%s'", name);
-                if (prop == PROP_CHASSIS && !valid_chassis(name))
-                        return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid chassis '%s'", name);
-                if (prop == PROP_DEPLOYMENT && !valid_deployment(name))
-                        return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid deployment '%s'", name);
-                if (prop == PROP_LOCATION && string_has_cc(name, NULL))
-                        return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid location '%s'", name);
-
-                h = strdup(name);
-                if (!h)
-                        return -ENOMEM;
-
-                free(c->data[prop]);
-                c->data[prop] = h;
-        }
+        r = free_and_strdup(&c->data[prop], name);
+        if (r < 0)
+                return r;
 
         r = context_write_data_machine_info(c);
         if (r < 0) {
index ec241d2f36d2c90bbf494272be85fc1d87d265f9..ff194dd95176c472458e0c61c3cc29ec5ac36aa8 100644 (file)
@@ -315,11 +315,11 @@ uint32_t jenkins_hashlittle( const void *key, size_t length, uint32_t initval)
      * then masks off the part it's not allowed to read.  Because the
      * string is aligned, the masked-off tail is in the same word as the
      * rest of the string.  Every machine with memory protection I've seen
-     * does it on word boundaries, so is OK with this.  But VALGRIND will
+     * does it on word boundaries, so is OK with this.  But valgrind will
      * still catch it and complain.  The masking trick does make the hash
      * noticeably faster for short strings (like English words).
      */
-#if !defined(VALGRIND) && !defined(__SANITIZE_ADDRESS__)
+#if !VALGRIND && !defined(__SANITIZE_ADDRESS__)
 
     switch(length)
     {
@@ -500,11 +500,11 @@ void jenkins_hashlittle2(
      * then masks off the part it's not allowed to read.  Because the
      * string is aligned, the masked-off tail is in the same word as the
      * rest of the string.  Every machine with memory protection I've seen
-     * does it on word boundaries, so is OK with this.  But VALGRIND will
+     * does it on word boundaries, so is OK with this.  But valgrind will
      * still catch it and complain.  The masking trick does make the hash
      * noticeably faster for short strings (like English words).
      */
-#if !defined(VALGRIND) && !defined(__SANITIZE_ADDRESS__)
+#if !VALGRIND && !defined(__SANITIZE_ADDRESS__)
 
     switch(length)
     {
@@ -676,11 +676,11 @@ uint32_t jenkins_hashbig( const void *key, size_t length, uint32_t initval)
      * then shifts out the part it's not allowed to read.  Because the
      * string is aligned, the illegal read is in the same word as the
      * rest of the string.  Every machine with memory protection I've seen
-     * does it on word boundaries, so is OK with this.  But VALGRIND will
+     * does it on word boundaries, so is OK with this.  But valgrind will
      * still catch it and complain.  The masking trick does make the hash
      * noticeably faster for short strings (like English words).
      */
-#if !defined(VALGRIND) && !defined(__SANITIZE_ADDRESS__)
+#if !VALGRIND && !defined(__SANITIZE_ADDRESS__)
 
     switch(length)
     {
index d5640c549cf6a68be29c0f5721e5e4afa03ade1b..67466cf326dc02638e6a3f83b02b57714f12480c 100644 (file)
@@ -16,6 +16,7 @@
 #include "alloc-util.h"
 #include "catalog.h"
 #include "fd-util.h"
+#include "fs-util.h"
 #include "fileio.h"
 #include "log.h"
 #include "macro.h"
@@ -32,9 +33,8 @@ static const char *no_catalog_dirs[] = {
         NULL
 };
 
-static Hashmap * test_import(const char* contents, ssize_t size, int code) {
-        int r;
-        char name[] = "/tmp/test-catalog.XXXXXX";
+static Hashmap* test_import(const char* contents, ssize_t size, int code) {
+        _cleanup_(unlink_tempfilep) char name[] = "/tmp/test-catalog.XXXXXX";
         _cleanup_close_ int fd;
         Hashmap *h;
 
@@ -47,10 +47,7 @@ static Hashmap * test_import(const char* contents, ssize_t size, int code) {
         assert_se(fd >= 0);
         assert_se(write(fd, contents, size) == size);
 
-        r = catalog_import_file(h, name);
-        assert_se(r == code);
-
-        unlink(name);
+        assert_se(catalog_import_file(h, name) == code);
 
         return h;
 }
@@ -164,17 +161,9 @@ static void test_catalog_import_merge_no_body(void) {
         }
 }
 
-static const char* database = NULL;
-
-static void test_catalog_update(void) {
-        static char name[] = "/tmp/test-catalog.XXXXXX";
+static void test_catalog_update(const char *database) {
         int r;
 
-        r = mkostemp_safe(name);
-        assert_se(r >= 0);
-
-        database = name;
-
         /* Test what happens if there are no files. */
         r = catalog_update(database, NULL, NULL);
         assert_se(r == 0);
@@ -218,6 +207,7 @@ static void test_catalog_file_lang(void) {
 }
 
 int main(int argc, char *argv[]) {
+        _cleanup_(unlink_tempfilep) char database[] = "/tmp/test-catalog.XXXXXX";
         _cleanup_free_ char *text = NULL;
         int r;
 
@@ -234,7 +224,9 @@ int main(int argc, char *argv[]) {
         test_catalog_import_merge();
         test_catalog_import_merge_no_body();
 
-        test_catalog_update();
+        assert_se(mkostemp_safe(database) >= 0);
+
+        test_catalog_update(database);
 
         r = catalog_list(stdout, database, true);
         assert_se(r >= 0);
@@ -245,8 +237,5 @@ int main(int argc, char *argv[]) {
         assert_se(catalog_get(database, SD_MESSAGE_COREDUMP, &text) >= 0);
         printf(">>>%s<<<\n", text);
 
-        if (database)
-                unlink(database);
-
         return 0;
 }
index 1fb8a3e2fb64cb699d94105a97a8089434515d7a..f27a1f88dbc8bfcc8e063bdea19d43c795bf7ac3 100644 (file)
@@ -13,6 +13,7 @@
 #include "compress.h"
 #include "fd-util.h"
 #include "fileio.h"
+#include "fs-util.h"
 #include "macro.h"
 #include "path-util.h"
 #include "random-util.h"
@@ -142,8 +143,9 @@ static void test_compress_stream(int compression,
                                  const char *srcfile) {
 
         _cleanup_close_ int src = -1, dst = -1, dst2 = -1;
-        char pattern[] = "/tmp/systemd-test.compressed.XXXXXX",
-             pattern2[] = "/tmp/systemd-test.compressed.XXXXXX";
+        _cleanup_(unlink_tempfilep) char
+                pattern[] = "/tmp/systemd-test.compressed.XXXXXX",
+                pattern2[] = "/tmp/systemd-test.compressed.XXXXXX";
         int r;
         _cleanup_free_ char *cmd = NULL, *cmd2 = NULL;
         struct stat st = {};
@@ -195,9 +197,6 @@ static void test_compress_stream(int compression,
         assert_se(lseek(dst2, 0, SEEK_SET) == 0);
         r = decompress(dst, dst2, st.st_size - 1);
         assert_se(r == -EFBIG);
-
-        assert_se(unlink(pattern) == 0);
-        assert_se(unlink(pattern2) == 0);
 }
 #endif
 
index 98e8a7e25a2cc15c717bebacfabcba88fe1ee9ad..7aa121b85c875687fb7980384ca879a3be8e9bef 100644 (file)
@@ -539,7 +539,7 @@ int main(int argc, char *argv[]) {
         test_discover_message(e);
         test_addr_acq(e);
 
-#ifdef VALGRIND
+#if VALGRIND
         /* Make sure the async_close thread has finished.
          * valgrind would report some of the phread_* structures
          * as not cleaned up properly. */
index 5fa3e8d9607bb82294b805a810d62a61dde0642b..75f5e4d30eca78afb2196c7e94f25c66f25454b6 100644 (file)
@@ -18,6 +18,7 @@
 #include "bus-util.h"
 #include "fd-util.h"
 #include "format-util.h"
+#include "pager.h"
 #include "process-util.h"
 #include "signal-util.h"
 #include "strv.h"
@@ -28,6 +29,7 @@ static const char* arg_what = "idle:sleep:shutdown";
 static const char* arg_who = NULL;
 static const char* arg_why = "Unknown reason";
 static const char* arg_mode = NULL;
+static bool arg_no_pager = false;
 
 static enum {
         ACTION_INHIBIT,
@@ -69,6 +71,8 @@ static int print_inhibitors(sd_bus *bus, sd_bus_error *error) {
         unsigned n = 0;
         int r;
 
+        (void) pager_open(arg_no_pager, false);
+
         r = sd_bus_call_method(
                         bus,
                         "org.freedesktop.login1",
@@ -121,6 +125,7 @@ static void help(void) {
                "Execute a process while inhibiting shutdown/sleep/idle.\n\n"
                "  -h --help               Show this help\n"
                "     --version            Show package version\n"
+               "     --no-pager           Do not pipe output into a pager\n"
                "     --what=WHAT          Operations to inhibit, colon separated list of:\n"
                "                          shutdown, sleep, idle, handle-power-key,\n"
                "                          handle-suspend-key, handle-hibernate-key,\n"
@@ -141,6 +146,7 @@ static int parse_argv(int argc, char *argv[]) {
                 ARG_WHY,
                 ARG_MODE,
                 ARG_LIST,
+                ARG_NO_PAGER,
         };
 
         static const struct option options[] = {
@@ -151,6 +157,7 @@ static int parse_argv(int argc, char *argv[]) {
                 { "why",          required_argument, NULL, ARG_WHY          },
                 { "mode",         required_argument, NULL, ARG_MODE         },
                 { "list",         no_argument,       NULL, ARG_LIST         },
+                { "no-pager",     no_argument,       NULL, ARG_NO_PAGER     },
                 {}
         };
 
@@ -190,6 +197,10 @@ static int parse_argv(int argc, char *argv[]) {
                         arg_action = ACTION_LIST;
                         break;
 
+                case ARG_NO_PAGER:
+                        arg_no_pager = true;
+                        break;
+
                 case '?':
                         return -EINVAL;
 
@@ -231,6 +242,7 @@ int main(int argc, char *argv[]) {
         if (arg_action == ACTION_LIST) {
 
                 r = print_inhibitors(bus, &error);
+                pager_close();
                 if (r < 0) {
                         log_error("Failed to list inhibitors: %s", bus_error_message(&error, -r));
                         return EXIT_FAILURE;
index 32c8def610d99c09423823ffdde44560ae03f3bb..79a5be8af9cd58aed2680378e91c77be7b0d8b7e 100644 (file)
@@ -277,74 +277,9 @@ static int property_get_scheduled_shutdown(
 }
 
 static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_handle_action, handle_action, HandleAction);
-
-static int property_get_docked(
-                sd_bus *bus,
-                const char *path,
-                const char *interface,
-                const char *property,
-                sd_bus_message *reply,
-                void *userdata,
-                sd_bus_error *error) {
-
-        Manager *m = userdata;
-
-        assert(bus);
-        assert(reply);
-        assert(m);
-
-        return sd_bus_message_append(reply, "b", manager_is_docked_or_external_displays(m));
-}
-
-static int property_get_current_sessions(
-                sd_bus *bus,
-                const char *path,
-                const char *interface,
-                const char *property,
-                sd_bus_message *reply,
-                void *userdata,
-                sd_bus_error *error) {
-
-        Manager *m = userdata;
-
-        assert(bus);
-        assert(reply);
-        assert(m);
-
-        return sd_bus_message_append(reply, "t", (uint64_t) hashmap_size(m->sessions));
-}
-
-static int property_get_current_inhibitors(
-                sd_bus *bus,
-                const char *path,
-                const char *interface,
-                const char *property,
-                sd_bus_message *reply,
-                void *userdata,
-                sd_bus_error *error) {
-
-        Manager *m = userdata;
-
-        assert(bus);
-        assert(reply);
-        assert(m);
-
-        return sd_bus_message_append(reply, "t", (uint64_t) hashmap_size(m->inhibitors));
-}
-
-static int property_get_compat_user_tasks_max(
-                sd_bus *bus,
-                const char *path,
-                const char *interface,
-                const char *property,
-                sd_bus_message *reply,
-                void *userdata,
-                sd_bus_error *error) {
-
-        assert(reply);
-
-        return sd_bus_message_append(reply, "t", CGROUP_LIMIT_MAX);
-}
+static BUS_DEFINE_PROPERTY_GET(property_get_docked, "b", Manager, manager_is_docked_or_external_displays);
+static BUS_DEFINE_PROPERTY_GET_GLOBAL(property_get_compat_user_tasks_max, "t", CGROUP_LIMIT_MAX);
+static BUS_DEFINE_PROPERTY_GET_REF(property_get_hashmap_size, "t", Hashmap *, (uint64_t) hashmap_size);
 
 static int method_get_session(sd_bus_message *message, void *userdata, sd_bus_error *error) {
         _cleanup_free_ char *p = NULL;
@@ -2731,9 +2666,9 @@ const sd_bus_vtable manager_vtable[] = {
         SD_BUS_PROPERTY("RemoveIPC", "b", bus_property_get_bool, offsetof(Manager, remove_ipc), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("RuntimeDirectorySize", "t", bus_property_get_size, offsetof(Manager, runtime_dir_size), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("InhibitorsMax", "t", NULL, offsetof(Manager, inhibitors_max), SD_BUS_VTABLE_PROPERTY_CONST),
-        SD_BUS_PROPERTY("NCurrentInhibitors", "t", property_get_current_inhibitors, 0, 0),
+        SD_BUS_PROPERTY("NCurrentInhibitors", "t", property_get_hashmap_size, offsetof(Manager, inhibitors), 0),
         SD_BUS_PROPERTY("SessionsMax", "t", NULL, offsetof(Manager, sessions_max), SD_BUS_VTABLE_PROPERTY_CONST),
-        SD_BUS_PROPERTY("NCurrentSessions", "t", property_get_current_sessions, 0, 0),
+        SD_BUS_PROPERTY("NCurrentSessions", "t", property_get_hashmap_size, offsetof(Manager, sessions), 0),
         SD_BUS_PROPERTY("UserTasksMax", "t", property_get_compat_user_tasks_max, 0, SD_BUS_VTABLE_PROPERTY_CONST|SD_BUS_VTABLE_HIDDEN),
 
         SD_BUS_METHOD("GetSession", "s", "o", method_get_session, SD_BUS_VTABLE_UNPRIVILEGED),
index 56a06ccec349f09757fbcd87e6f51c7e73446162..720140d6e3620a8d698a2a67ce570fe5b85f11cc 100644 (file)
 #include "user-util.h"
 #include "util.h"
 
+static BUS_DEFINE_PROPERTY_GET(property_get_can_multi_session, "b", Seat, seat_can_multi_session);
+static BUS_DEFINE_PROPERTY_GET(property_get_can_tty, "b", Seat, seat_can_tty);
+static BUS_DEFINE_PROPERTY_GET(property_get_can_graphical, "b", Seat, seat_can_graphical);
+
 static int property_get_active_session(
                 sd_bus *bus,
                 const char *path,
@@ -41,60 +45,6 @@ static int property_get_active_session(
         return sd_bus_message_append(reply, "(so)", s->active ? s->active->id : "", p);
 }
 
-static int property_get_can_multi_session(
-                sd_bus *bus,
-                const char *path,
-                const char *interface,
-                const char *property,
-                sd_bus_message *reply,
-                void *userdata,
-                sd_bus_error *error) {
-
-        Seat *s = userdata;
-
-        assert(bus);
-        assert(reply);
-        assert(s);
-
-        return sd_bus_message_append(reply, "b", seat_can_multi_session(s));
-}
-
-static int property_get_can_tty(
-                sd_bus *bus,
-                const char *path,
-                const char *interface,
-                const char *property,
-                sd_bus_message *reply,
-                void *userdata,
-                sd_bus_error *error) {
-
-        Seat *s = userdata;
-
-        assert(bus);
-        assert(reply);
-        assert(s);
-
-        return sd_bus_message_append(reply, "b", seat_can_tty(s));
-}
-
-static int property_get_can_graphical(
-                sd_bus *bus,
-                const char *path,
-                const char *interface,
-                const char *property,
-                sd_bus_message *reply,
-                void *userdata,
-                sd_bus_error *error) {
-
-        Seat *s = userdata;
-
-        assert(bus);
-        assert(reply);
-        assert(s);
-
-        return sd_bus_message_append(reply, "b", seat_can_graphical(s));
-}
-
 static int property_get_sessions(
                 sd_bus *bus,
                 const char *path,
index e4edf0a26bd4836be08a63aaf6b00f3f84503145..81afc2337da42be5dfd4344afa5c4a0c92cad38a 100644 (file)
@@ -86,42 +86,8 @@ static int property_get_seat(
 
 static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_type, session_type, SessionType);
 static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_class, session_class, SessionClass);
-
-static int property_get_active(
-                sd_bus *bus,
-                const char *path,
-                const char *interface,
-                const char *property,
-                sd_bus_message *reply,
-                void *userdata,
-                sd_bus_error *error) {
-
-        Session *s = userdata;
-
-        assert(bus);
-        assert(reply);
-        assert(s);
-
-        return sd_bus_message_append(reply, "b", session_is_active(s));
-}
-
-static int property_get_state(
-                sd_bus *bus,
-                const char *path,
-                const char *interface,
-                const char *property,
-                sd_bus_message *reply,
-                void *userdata,
-                sd_bus_error *error) {
-
-        Session *s = userdata;
-
-        assert(bus);
-        assert(reply);
-        assert(s);
-
-        return sd_bus_message_append(reply, "s", session_state_to_string(session_get_state(s)));
-}
+static BUS_DEFINE_PROPERTY_GET(property_get_active, "b", Session, session_is_active);
+static BUS_DEFINE_PROPERTY_GET2(property_get_state, "s", Session, session_get_state, session_state_to_string);
 
 static int property_get_idle_hint(
                 sd_bus *bus,
index cc694b672509fd9aaa9ef54dd8bd480f66f658ea..48bf2d947aa59b77dc778c9cf9e95200084d84cf 100644 (file)
@@ -17,6 +17,8 @@
 #include "strv.h"
 #include "user-util.h"
 
+static BUS_DEFINE_PROPERTY_GET2(property_get_state, "s", User, user_get_state, user_state_to_string);
+
 static int property_get_display(
                 sd_bus *bus,
                 const char *path,
@@ -40,24 +42,6 @@ static int property_get_display(
         return sd_bus_message_append(reply, "(so)", u->display ? u->display->id : "", p);
 }
 
-static int property_get_state(
-                sd_bus *bus,
-                const char *path,
-                const char *interface,
-                const char *property,
-                sd_bus_message *reply,
-                void *userdata,
-                sd_bus_error *error) {
-
-        User *u = userdata;
-
-        assert(bus);
-        assert(reply);
-        assert(u);
-
-        return sd_bus_message_append(reply, "s", user_state_to_string(user_get_state(u)));
-}
-
 static int property_get_sessions(
                 sd_bus *bus,
                 const char *path,
index c8785cc9279e6a633b422b2605819c34316c2cbd..058543fbb21a0312f0b564869fa3978b0096c116 100644 (file)
 #include "terminal-util.h"
 #include "user-util.h"
 
-static int property_get_state(
-                sd_bus *bus,
-                const char *path,
-                const char *interface,
-                const char *property,
-                sd_bus_message *reply,
-                void *userdata,
-                sd_bus_error *error) {
-
-        Machine *m = userdata;
-        const char *state;
-        int r;
-
-        assert(bus);
-        assert(reply);
-        assert(m);
-
-        state = machine_state_to_string(machine_get_state(m));
-
-        r = sd_bus_message_append_basic(reply, 's', state);
-        if (r < 0)
-                return r;
-
-        return 1;
-}
+static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_class, machine_class, MachineClass);
+static BUS_DEFINE_PROPERTY_GET2(property_get_state, "s", Machine, machine_get_state, machine_state_to_string);
 
 static int property_get_netif(
                 sd_bus *bus,
@@ -85,8 +62,6 @@ static int property_get_netif(
         return sd_bus_message_append_array(reply, 'i', m->netif, m->n_netif * sizeof(int));
 }
 
-static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_class, machine_class, MachineClass);
-
 int bus_machine_method_terminate(sd_bus_message *message, void *userdata, sd_bus_error *error) {
         Machine *m = userdata;
         int r;
index 42ad47dc5317b8cc56553282f8ad57f35d21d1c6..2ac4689ba1d5c32424f1a5b39e8221a48f4f1d78 100644 (file)
 #include "unit-name.h"
 #include "user-util.h"
 
-static int property_get_pool_path(
-                sd_bus *bus,
-                const char *path,
-                const char *interface,
-                const char *property,
-                sd_bus_message *reply,
-                void *userdata,
-                sd_bus_error *error) {
-
-        assert(bus);
-        assert(reply);
-
-        return sd_bus_message_append(reply, "s", "/var/lib/machines");
-}
+static BUS_DEFINE_PROPERTY_GET_GLOBAL(property_get_pool_path, "s", "/var/lib/machines");
 
 static int property_get_pool_usage(
                 sd_bus *bus,
index ea66971fac710b42cdfaeece952a219641ccef74..f8234e75d489ed24f431bda542820326a026ec22 100644 (file)
@@ -18,35 +18,55 @@ struct ConfigPerfItem;
 %struct-type
 %includes
 %%
-Exec.Boot,                    config_parse_boot,          0, 0
-Exec.ProcessTwo,              config_parse_pid2,          0, 0
-Exec.Parameters,              config_parse_strv,          0, offsetof(Settings, parameters)
-Exec.Environment,             config_parse_strv,          0, offsetof(Settings, environment)
-Exec.User,                    config_parse_string,        0, offsetof(Settings, user)
-Exec.Capability,              config_parse_capability,    0, offsetof(Settings, capability)
-Exec.DropCapability,          config_parse_capability,    0, offsetof(Settings, drop_capability)
-Exec.KillSignal,              config_parse_signal,        0, offsetof(Settings, kill_signal)
-Exec.Personality,             config_parse_personality,   0, offsetof(Settings, personality)
-Exec.MachineID,               config_parse_id128,         0, offsetof(Settings, machine_id)
-Exec.WorkingDirectory,        config_parse_path,          0, offsetof(Settings, working_directory)
-Exec.PivotRoot,               config_parse_pivot_root,    0, 0
-Exec.PrivateUsers,            config_parse_private_users, 0, 0
-Exec.NotifyReady,             config_parse_bool,          0, offsetof(Settings, notify_ready)
-Exec.SystemCallFilter,        config_parse_syscall_filter,0, 0,
-Files.ReadOnly,               config_parse_tristate,      0, offsetof(Settings, read_only)
-Files.Volatile,               config_parse_volatile_mode, 0, offsetof(Settings, volatile_mode)
-Files.Bind,                   config_parse_bind,          0, 0
-Files.BindReadOnly,           config_parse_bind,          1, 0
-Files.TemporaryFileSystem,    config_parse_tmpfs,         0, 0
-Files.Overlay,                config_parse_overlay,       0, 0
-Files.OverlayReadOnly,        config_parse_overlay,       1, 0
-Files.PrivateUsersChown,      config_parse_tristate,      0, offsetof(Settings, userns_chown)
-Network.Private,              config_parse_tristate,      0, offsetof(Settings, private_network)
-Network.Interface,            config_parse_strv,          0, offsetof(Settings, network_interfaces)
-Network.MACVLAN,              config_parse_strv,          0, offsetof(Settings, network_macvlan)
-Network.IPVLAN,               config_parse_strv,          0, offsetof(Settings, network_ipvlan)
-Network.VirtualEthernet,      config_parse_tristate,      0, offsetof(Settings, network_veth)
-Network.VirtualEthernetExtra, config_parse_veth_extra,    0, 0
-Network.Bridge,               config_parse_ifname,        0, offsetof(Settings, network_bridge)
-Network.Zone,                 config_parse_network_zone,  0, 0
-Network.Port,                 config_parse_expose_port,   0, 0
+Exec.Boot,                    config_parse_boot,           0,                 0
+Exec.ProcessTwo,              config_parse_pid2,           0,                 0
+Exec.Parameters,              config_parse_strv,           0,                 offsetof(Settings, parameters)
+Exec.Environment,             config_parse_strv,           0,                 offsetof(Settings, environment)
+Exec.User,                    config_parse_string,         0,                 offsetof(Settings, user)
+Exec.Capability,              config_parse_capability,     0,                 offsetof(Settings, capability)
+Exec.DropCapability,          config_parse_capability,     0,                 offsetof(Settings, drop_capability)
+Exec.KillSignal,              config_parse_signal,         0,                 offsetof(Settings, kill_signal)
+Exec.Personality,             config_parse_personality,    0,                 offsetof(Settings, personality)
+Exec.MachineID,               config_parse_id128,          0,                 offsetof(Settings, machine_id)
+Exec.WorkingDirectory,        config_parse_path,           0,                 offsetof(Settings, working_directory)
+Exec.PivotRoot,               config_parse_pivot_root,     0,                 0
+Exec.PrivateUsers,            config_parse_private_users,  0,                 0
+Exec.NotifyReady,             config_parse_bool,           0,                 offsetof(Settings, notify_ready)
+Exec.SystemCallFilter,        config_parse_syscall_filter, 0,                 0,
+Exec.LimitCPU,                config_parse_rlimit,         RLIMIT_CPU,        offsetof(Settings, rlimit)
+Exec.LimitFSIZE,              config_parse_rlimit,         RLIMIT_FSIZE,      offsetof(Settings, rlimit)
+Exec.LimitDATA,               config_parse_rlimit,         RLIMIT_DATA,       offsetof(Settings, rlimit)
+Exec.LimitSTACK,              config_parse_rlimit,         RLIMIT_STACK,      offsetof(Settings, rlimit)
+Exec.LimitCORE,               config_parse_rlimit,         RLIMIT_CORE,       offsetof(Settings, rlimit)
+Exec.LimitRSS,                config_parse_rlimit,         RLIMIT_RSS,        offsetof(Settings, rlimit)
+Exec.LimitNOFILE,             config_parse_rlimit,         RLIMIT_NOFILE,     offsetof(Settings, rlimit)
+Exec.LimitAS,                 config_parse_rlimit,         RLIMIT_AS,         offsetof(Settings, rlimit)
+Exec.LimitNPROC,              config_parse_rlimit,         RLIMIT_NPROC,      offsetof(Settings, rlimit)
+Exec.LimitMEMLOCK,            config_parse_rlimit,         RLIMIT_MEMLOCK,    offsetof(Settings, rlimit)
+Exec.LimitLOCKS,              config_parse_rlimit,         RLIMIT_LOCKS,      offsetof(Settings, rlimit)
+Exec.LimitSIGPENDING,         config_parse_rlimit,         RLIMIT_SIGPENDING, offsetof(Settings, rlimit)
+Exec.LimitMSGQUEUE,           config_parse_rlimit,         RLIMIT_MSGQUEUE,   offsetof(Settings, rlimit)
+Exec.LimitNICE,               config_parse_rlimit,         RLIMIT_NICE,       offsetof(Settings, rlimit)
+Exec.LimitRTPRIO,             config_parse_rlimit,         RLIMIT_RTPRIO,     offsetof(Settings, rlimit)
+Exec.LimitRTTIME,             config_parse_rlimit,         RLIMIT_RTTIME,     offsetof(Settings, rlimit)
+Exec.Hostname,                config_parse_hostname,       0,                 offsetof(Settings, hostname)
+Exec.NoNewPrivileges,         config_parse_tristate,       0,                 offsetof(Settings, no_new_privileges)
+Exec.OOMScoreAdjust,          config_parse_oom_score_adjust, 0,               0
+Exec.CPUAffinity,             config_parse_cpu_affinity,   0,                 0
+Files.ReadOnly,               config_parse_tristate,       0,                 offsetof(Settings, read_only)
+Files.Volatile,               config_parse_volatile_mode,  0,                 offsetof(Settings, volatile_mode)
+Files.Bind,                   config_parse_bind,           0,                 0
+Files.BindReadOnly,           config_parse_bind,           1,                 0
+Files.TemporaryFileSystem,    config_parse_tmpfs,          0,                 0
+Files.Overlay,                config_parse_overlay,        0,                 0
+Files.OverlayReadOnly,        config_parse_overlay,        1,                 0
+Files.PrivateUsersChown,      config_parse_tristate,       0,                 offsetof(Settings, userns_chown)
+Network.Private,              config_parse_tristate,       0,                 offsetof(Settings, private_network)
+Network.Interface,            config_parse_strv,           0,                 offsetof(Settings, network_interfaces)
+Network.MACVLAN,              config_parse_strv,           0,                 offsetof(Settings, network_macvlan)
+Network.IPVLAN,               config_parse_strv,           0,                 offsetof(Settings, network_ipvlan)
+Network.VirtualEthernet,      config_parse_tristate,       0,                 offsetof(Settings, network_veth)
+Network.VirtualEthernetExtra, config_parse_veth_extra,     0,                 0
+Network.Bridge,               config_parse_ifname,         0,                 offsetof(Settings, network_bridge)
+Network.Zone,                 config_parse_network_zone,   0,                 0
+Network.Port,                 config_parse_expose_port,    0,                 0
index 487514d40a956f4132e7d5fae6fe456cb241cf7c..0acf718456b66f2c05ac2149b2bd1b60e3a4bdb6 100644 (file)
@@ -8,10 +8,13 @@
 #include "alloc-util.h"
 #include "cap-list.h"
 #include "conf-parser.h"
+#include "cpu-set-util.h"
+#include "hostname-util.h"
 #include "nspawn-network.h"
 #include "nspawn-settings.h"
 #include "parse-util.h"
 #include "process-util.h"
+#include "rlimit-util.h"
 #include "socket-util.h"
 #include "string-util.h"
 #include "strv.h"
@@ -34,6 +37,7 @@ int settings_load(FILE *f, const char *path, Settings **ret) {
         s->userns_mode = _USER_NAMESPACE_MODE_INVALID;
         s->uid_shift = UID_INVALID;
         s->uid_range = UID_INVALID;
+        s->no_new_privileges = -1;
 
         s->read_only = -1;
         s->volatile_mode = _VOLATILE_MODE_INVALID;
@@ -80,6 +84,9 @@ Settings* settings_free(Settings *s) {
         free(s->working_directory);
         strv_free(s->syscall_whitelist);
         strv_free(s->syscall_blacklist);
+        rlimit_free_all(s->rlimit);
+        free(s->hostname);
+        s->cpuset = cpu_set_mfree(s->cpuset);
 
         strv_free(s->network_interfaces);
         strv_free(s->network_macvlan);
@@ -601,3 +608,119 @@ int config_parse_syscall_filter(
 
         return 0;
 }
+
+int config_parse_hostname(
+                const char *unit,
+                const char *filename,
+                unsigned line,
+                const char *section,
+                unsigned section_line,
+                const char *lvalue,
+                int ltype,
+                const char *rvalue,
+                void *data,
+                void *userdata) {
+
+        char **s = data;
+
+        assert(rvalue);
+        assert(s);
+
+        if (!hostname_is_valid(rvalue, false)) {
+                log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid hostname, ignoring: %s", rvalue);
+                return 0;
+        }
+
+        if (free_and_strdup(s, empty_to_null(rvalue)) < 0)
+                return log_oom();
+
+        return 0;
+}
+
+int config_parse_oom_score_adjust(
+                const char *unit,
+                const char *filename,
+                unsigned line,
+                const char *section,
+                unsigned section_line,
+                const char *lvalue,
+                int ltype,
+                const char *rvalue,
+                void *data,
+                void *userdata) {
+
+        Settings *settings = data;
+        int oa, r;
+
+        assert(rvalue);
+        assert(settings);
+
+        if (isempty(rvalue)) {
+                settings->oom_score_adjust_set = false;
+                return 0;
+        }
+
+        r = parse_oom_score_adjust(rvalue, &oa);
+        if (r == -ERANGE) {
+                log_syntax(unit, LOG_ERR, filename, line, r, "OOM score adjust value out of range, ignoring: %s", rvalue);
+                return 0;
+        }
+        if (r < 0) {
+                log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse the OOM score adjust value, ignoring: %s", rvalue);
+                return 0;
+        }
+
+        settings->oom_score_adjust = oa;
+        settings->oom_score_adjust_set = true;
+
+        return 0;
+}
+
+int config_parse_cpu_affinity(
+                const char *unit,
+                const char *filename,
+                unsigned line,
+                const char *section,
+                unsigned section_line,
+                const char *lvalue,
+                int ltype,
+                const char *rvalue,
+                void *data,
+                void *userdata) {
+
+        _cleanup_cpu_free_ cpu_set_t *cpuset = NULL;
+        Settings *settings = data;
+        int ncpus;
+
+        assert(rvalue);
+        assert(settings);
+
+        ncpus = parse_cpu_set_and_warn(rvalue, &cpuset, unit, filename, line, lvalue);
+        if (ncpus < 0)
+                return ncpus;
+
+        if (ncpus == 0) {
+                /* An empty assignment resets the CPU list */
+                settings->cpuset = cpu_set_mfree(settings->cpuset);
+                settings->cpuset_ncpus = 0;
+                return 0;
+        }
+
+        if (!settings->cpuset) {
+                settings->cpuset = TAKE_PTR(cpuset);
+                settings->cpuset_ncpus = (unsigned) ncpus;
+                return 0;
+        }
+
+        if (settings->cpuset_ncpus < (unsigned) ncpus) {
+                CPU_OR_S(CPU_ALLOC_SIZE(settings->cpuset_ncpus), cpuset, settings->cpuset, cpuset);
+                CPU_FREE(settings->cpuset);
+                settings->cpuset = TAKE_PTR(cpuset);
+                settings->cpuset_ncpus = (unsigned) ncpus;
+                return 0;
+        }
+
+        CPU_OR_S(CPU_ALLOC_SIZE((unsigned) ncpus), settings->cpuset, settings->cpuset, cpuset);
+
+        return 0;
+}
index 731db87260689661dc753b6668de25c589565d9c..c786bf8c86b66572af8cb6ce7643a9a1ef2259e8 100644 (file)
@@ -7,6 +7,7 @@
   Copyright 2015 Lennart Poettering
 ***/
 
+#include <sched.h>
 #include <stdio.h>
 
 #include "sd-id128.h"
@@ -32,24 +33,30 @@ typedef enum UserNamespaceMode {
 } UserNamespaceMode;
 
 typedef enum SettingsMask {
-        SETTING_START_MODE        = 1 << 0,
-        SETTING_ENVIRONMENT       = 1 << 1,
-        SETTING_USER              = 1 << 2,
-        SETTING_CAPABILITY        = 1 << 3,
-        SETTING_KILL_SIGNAL       = 1 << 4,
-        SETTING_PERSONALITY       = 1 << 5,
-        SETTING_MACHINE_ID        = 1 << 6,
-        SETTING_NETWORK           = 1 << 7,
-        SETTING_EXPOSE_PORTS      = 1 << 8,
-        SETTING_READ_ONLY         = 1 << 9,
-        SETTING_VOLATILE_MODE     = 1 << 10,
-        SETTING_CUSTOM_MOUNTS     = 1 << 11,
-        SETTING_WORKING_DIRECTORY = 1 << 12,
-        SETTING_USERNS            = 1 << 13,
-        SETTING_NOTIFY_READY      = 1 << 14,
-        SETTING_PIVOT_ROOT        = 1 << 15,
-        SETTING_SYSCALL_FILTER    = 1 << 16,
-        _SETTINGS_MASK_ALL        = (1 << 17) -1
+        SETTING_START_MODE        = UINT64_C(1) << 0,
+        SETTING_ENVIRONMENT       = UINT64_C(1) << 1,
+        SETTING_USER              = UINT64_C(1) << 2,
+        SETTING_CAPABILITY        = UINT64_C(1) << 3,
+        SETTING_KILL_SIGNAL       = UINT64_C(1) << 4,
+        SETTING_PERSONALITY       = UINT64_C(1) << 5,
+        SETTING_MACHINE_ID        = UINT64_C(1) << 6,
+        SETTING_NETWORK           = UINT64_C(1) << 7,
+        SETTING_EXPOSE_PORTS      = UINT64_C(1) << 8,
+        SETTING_READ_ONLY         = UINT64_C(1) << 9,
+        SETTING_VOLATILE_MODE     = UINT64_C(1) << 10,
+        SETTING_CUSTOM_MOUNTS     = UINT64_C(1) << 11,
+        SETTING_WORKING_DIRECTORY = UINT64_C(1) << 12,
+        SETTING_USERNS            = UINT64_C(1) << 13,
+        SETTING_NOTIFY_READY      = UINT64_C(1) << 14,
+        SETTING_PIVOT_ROOT        = UINT64_C(1) << 15,
+        SETTING_SYSCALL_FILTER    = UINT64_C(1) << 16,
+        SETTING_HOSTNAME          = UINT64_C(1) << 17,
+        SETTING_NO_NEW_PRIVILEGES = UINT64_C(1) << 18,
+        SETTING_OOM_SCORE_ADJUST  = UINT64_C(1) << 19,
+        SETTING_CPU_AFFINITY      = UINT64_C(1) << 20,
+        SETTING_RLIMIT_FIRST      = UINT64_C(1) << 21, /* we define one bit per resource limit here */
+        SETTING_RLIMIT_LAST       = UINT64_C(1) << (21 + _RLIMIT_MAX - 1),
+        _SETTINGS_MASK_ALL        = (UINT64_C(1) << (21 + _RLIMIT_MAX)) - 1
 } SettingsMask;
 
 typedef struct Settings {
@@ -71,6 +78,13 @@ typedef struct Settings {
         bool notify_ready;
         char **syscall_whitelist;
         char **syscall_blacklist;
+        struct rlimit *rlimit[_RLIMIT_MAX];
+        char *hostname;
+        int no_new_privileges;
+        int oom_score_adjust;
+        bool oom_score_adjust_set;
+        cpu_set_t *cpuset;
+        unsigned cpuset_ncpus;
 
         /* [Image] */
         int read_only;
@@ -115,3 +129,6 @@ int config_parse_boot(const char *unit, const char *filename, unsigned line, con
 int config_parse_pid2(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
 int config_parse_private_users(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
 int config_parse_syscall_filter(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+int config_parse_hostname(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+int config_parse_oom_score_adjust(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+int config_parse_cpu_affinity(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
index 12eaa6c0d74bd5d894ad8a63f08e56e9866cd171..b5d9de8da0f69293a1794ad219573ae0a8542964 100644 (file)
@@ -43,6 +43,7 @@
 #include "capability-util.h"
 #include "cgroup-util.h"
 #include "copy.h"
+#include "cpu-set-util.h"
 #include "dev-setup.h"
 #include "dissect-image.h"
 #include "env-util.h"
 #include "nspawn-settings.h"
 #include "nspawn-setuid.h"
 #include "nspawn-stub-pid1.h"
+#include "pager.h"
 #include "parse-util.h"
 #include "path-util.h"
 #include "process-util.h"
 #include "ptyfwd.h"
 #include "random-util.h"
 #include "raw-clone.h"
+#include "rlimit-util.h"
 #include "rm-rf.h"
 #include "selinux-util.h"
 #include "signal-util.h"
@@ -127,7 +130,8 @@ static char *arg_pivot_root_new = NULL;
 static char *arg_pivot_root_old = NULL;
 static char *arg_user = NULL;
 static sd_id128_t arg_uuid = {};
-static char *arg_machine = NULL;
+static char *arg_machine = NULL;     /* The name used by the host to refer to this */
+static char *arg_hostname = NULL;    /* The name the payload sees by default */
 static const char *arg_selinux_context = NULL;
 static const char *arg_selinux_apifs_context = NULL;
 static const char *arg_slice = NULL;
@@ -200,8 +204,17 @@ static void *arg_root_hash = NULL;
 static size_t arg_root_hash_size = 0;
 static char **arg_syscall_whitelist = NULL;
 static char **arg_syscall_blacklist = NULL;
+static struct rlimit *arg_rlimit[_RLIMIT_MAX] = {};
+static bool arg_no_new_privileges = false;
+static int arg_oom_score_adjust = 0;
+static bool arg_oom_score_adjust_set = false;
+static cpu_set_t *arg_cpuset = NULL;
+static unsigned arg_cpuset_ncpus = 0;
 
 static void help(void) {
+
+        (void) pager_open(false, false);
+
         printf("%s [OPTIONS...] [PATH] [ARGUMENTS...]\n\n"
                "Spawn a minimal namespace container for debugging, testing and building.\n\n"
                "  -h --help                 Show this help\n"
@@ -221,6 +234,7 @@ static void help(void) {
                "                            Pivot root to given directory in the container\n"
                "  -u --user=USER            Run the command under specified user or uid\n"
                "  -M --machine=NAME         Set the machine name for the container\n"
+               "     --hostname=NAME        Override the hostname for the container\n"
                "     --uuid=UUID            Set a specific machine UUID for the container\n"
                "  -S --slice=SLICE          Place the container in the specified slice\n"
                "     --property=NAME=VALUE  Set scope unit property\n"
@@ -264,6 +278,10 @@ static void help(void) {
                "     --drop-capability=CAP  Drop the specified capability from the default set\n"
                "     --system-call-filter=LIST|~LIST\n"
                "                            Permit/prohibit specific system calls\n"
+               "     --rlimit=NAME=LIMIT    Set a resource limit for the payload\n"
+               "     --oom-score-adjust=VALUE\n"
+               "                            Adjust the OOM score value for the payload\n"
+               "     --cpu-affinity=CPUS    Adjust the CPU affinity of the container\n"
                "     --kill-signal=SIGNAL   Select signal to use for shutting down PID 1\n"
                "     --link-journal=MODE    Link up guest journal, one of no, auto, guest, \n"
                "                            host, try-guest, try-host\n"
@@ -439,6 +457,11 @@ static int parse_argv(int argc, char *argv[]) {
                 ARG_NOTIFY_READY,
                 ARG_ROOT_HASH,
                 ARG_SYSTEM_CALL_FILTER,
+                ARG_RLIMIT,
+                ARG_HOSTNAME,
+                ARG_NO_NEW_PRIVILEGES,
+                ARG_OOM_SCORE_ADJUST,
+                ARG_CPU_AFFINITY,
         };
 
         static const struct option options[] = {
@@ -455,6 +478,7 @@ static int parse_argv(int argc, char *argv[]) {
                 { "read-only",              no_argument,       NULL, ARG_READ_ONLY              },
                 { "capability",             required_argument, NULL, ARG_CAPABILITY             },
                 { "drop-capability",        required_argument, NULL, ARG_DROP_CAPABILITY        },
+                { "no-new-privileges",      required_argument, NULL, ARG_NO_NEW_PRIVILEGES      },
                 { "link-journal",           required_argument, NULL, ARG_LINK_JOURNAL           },
                 { "bind",                   required_argument, NULL, ARG_BIND                   },
                 { "bind-ro",                required_argument, NULL, ARG_BIND_RO                },
@@ -462,6 +486,7 @@ static int parse_argv(int argc, char *argv[]) {
                 { "overlay",                required_argument, NULL, ARG_OVERLAY                },
                 { "overlay-ro",             required_argument, NULL, ARG_OVERLAY_RO             },
                 { "machine",                required_argument, NULL, 'M'                        },
+                { "hostname",               required_argument, NULL, ARG_HOSTNAME               },
                 { "slice",                  required_argument, NULL, 'S'                        },
                 { "setenv",                 required_argument, NULL, 'E'                        },
                 { "selinux-context",        required_argument, NULL, 'Z'                        },
@@ -492,6 +517,9 @@ static int parse_argv(int argc, char *argv[]) {
                 { "notify-ready",           required_argument, NULL, ARG_NOTIFY_READY           },
                 { "root-hash",              required_argument, NULL, ARG_ROOT_HASH              },
                 { "system-call-filter",     required_argument, NULL, ARG_SYSTEM_CALL_FILTER     },
+                { "rlimit",                 required_argument, NULL, ARG_RLIMIT                 },
+                { "oom-score-adjust",       required_argument, NULL, ARG_OOM_SCORE_ADJUST       },
+                { "cpu-affinity",           required_argument, NULL, ARG_CPU_AFFINITY           },
                 {}
         };
 
@@ -696,6 +724,23 @@ static int parse_argv(int argc, char *argv[]) {
                         }
                         break;
 
+                case ARG_HOSTNAME:
+                        if (isempty(optarg))
+                                arg_hostname = mfree(arg_hostname);
+                        else {
+                                if (!hostname_is_valid(optarg, false)) {
+                                        log_error("Invalid hostname: %s", optarg);
+                                        return -EINVAL;
+                                }
+
+                                r = free_and_strdup(&arg_hostname, optarg);
+                                if (r < 0)
+                                        return log_oom();
+                        }
+
+                        arg_settings_mask |= SETTING_HOSTNAME;
+                        break;
+
                 case 'Z':
                         arg_selinux_context = optarg;
                         break;
@@ -747,6 +792,15 @@ static int parse_argv(int argc, char *argv[]) {
                         break;
                 }
 
+                case ARG_NO_NEW_PRIVILEGES:
+                        r = parse_boolean(optarg);
+                        if (r < 0)
+                                return log_error_errno(r, "Failed to parse --no-new-privileges= argument: %s", optarg);
+
+                        arg_no_new_privileges = r;
+                        arg_settings_mask |= SETTING_NO_NEW_PRIVILEGES;
+                        break;
+
                 case 'j':
                         arg_link_journal = LINK_GUEST;
                         arg_link_journal_try = true;
@@ -1094,6 +1148,66 @@ static int parse_argv(int argc, char *argv[]) {
                         break;
                 }
 
+                case ARG_RLIMIT: {
+                        const char *eq;
+                        char *name;
+                        int rl;
+
+                        eq = strchr(optarg, '=');
+                        if (!eq) {
+                                log_error("--rlimit= expects an '=' assignment.");
+                                return -EINVAL;
+                        }
+
+                        name = strndup(optarg, eq - optarg);
+                        if (!name)
+                                return log_oom();
+
+                        rl = rlimit_from_string_harder(name);
+                        if (rl < 0) {
+                                log_error("Unknown resource limit: %s", name);
+                                return -EINVAL;
+                        }
+
+                        if (!arg_rlimit[rl]) {
+                                arg_rlimit[rl] = new0(struct rlimit, 1);
+                                if (!arg_rlimit[rl])
+                                        return log_oom();
+                        }
+
+                        r = rlimit_parse(rl, eq + 1, arg_rlimit[rl]);
+                        if (r < 0)
+                                return log_error_errno(r, "Failed to parse resource limit: %s", eq + 1);
+
+                        arg_settings_mask |= SETTING_RLIMIT_FIRST << rl;
+                        break;
+                }
+
+                case ARG_OOM_SCORE_ADJUST:
+                        r = parse_oom_score_adjust(optarg, &arg_oom_score_adjust);
+                        if (r < 0)
+                                return log_error_errno(r, "Failed to parse --oom-score-adjust= parameter: %s", optarg);
+
+                        arg_oom_score_adjust_set = true;
+                        arg_settings_mask |= SETTING_OOM_SCORE_ADJUST;
+                        break;
+
+                case ARG_CPU_AFFINITY: {
+                        _cleanup_cpu_free_ cpu_set_t *cpuset = NULL;
+
+                        r = parse_cpu_set(optarg, &cpuset);
+                        if (r < 0)
+                                return log_error_errno(r, "Failed to parse CPU affinity mask: %s", optarg);
+
+                        if (arg_cpuset)
+                                CPU_FREE(arg_cpuset);
+
+                        arg_cpuset = TAKE_PTR(cpuset);
+                        arg_cpuset_ncpus = r;
+                        arg_settings_mask |= SETTING_CPU_AFFINITY;
+                        break;
+                }
+
                 case '?':
                         return -EINVAL;
 
@@ -1718,12 +1832,14 @@ static int on_address_change(sd_netlink *rtnl, sd_netlink_message *m, void *user
 }
 
 static int setup_hostname(void) {
+        int r;
 
         if ((arg_clone_ns_flags & CLONE_NEWUTS) == 0)
                 return 0;
 
-        if (sethostname_idempotent(arg_machine) < 0)
-                return -errno;
+        r = sethostname_idempotent(arg_hostname ?: arg_machine);
+        if (r < 0)
+                return log_error_errno(r, "Failed to set hostname: %m");
 
         return 0;
 }
@@ -2282,7 +2398,6 @@ static int inner_child(
                 NULL
         };
         const char *exec_target;
-
         _cleanup_strv_free_ char **env_use = NULL;
         int r;
 
@@ -2377,11 +2492,21 @@ static int inner_child(
                 rtnl_socket = safe_close(rtnl_socket);
         }
 
+        if (arg_oom_score_adjust_set) {
+                r = set_oom_score_adjust(arg_oom_score_adjust);
+                if (r < 0)
+                        return log_error_errno(r, "Failed to adjust OOM score: %m");
+        }
+
+        if (arg_cpuset)
+                if (sched_setaffinity(0, CPU_ALLOC_SIZE(arg_cpuset_ncpus), arg_cpuset) < 0)
+                        return log_error_errno(errno, "Failed to set CPU affinity: %m");
+
         r = drop_capabilities();
         if (r < 0)
                 return log_error_errno(r, "drop_capabilities() failed: %m");
 
-        setup_hostname();
+        (void) setup_hostname();
 
         if (arg_personality != PERSONALITY_INVALID) {
                 r = safe_personality(arg_personality);
@@ -2403,6 +2528,10 @@ static int inner_child(
         if (r < 0)
                 return r;
 
+        if (arg_no_new_privileges)
+                if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) < 0)
+                        return log_error_errno(errno, "Failed to disable new privileges: %m");
+
         /* LXC sets container=lxc, so follow the scheme here */
         envp[n_env++] = strjoina("container=", arg_container_service_name);
 
@@ -2559,10 +2688,10 @@ static int outer_child(
                 FDSet *fds,
                 int netns_fd) {
 
+        _cleanup_close_ int fd = -1;
+        int r, which_failed;
         pid_t pid;
         ssize_t l;
-        int r;
-        _cleanup_close_ int fd = -1;
 
         assert(barrier);
         assert(directory);
@@ -2805,6 +2934,10 @@ static int outer_child(
         if (fd < 0)
                 return fd;
 
+        r = setrlimit_closest_all((const struct rlimit *const*) arg_rlimit, &which_failed);
+        if (r < 0)
+                return log_error_errno(r, "Failed to apply resource limit RLIMIT_%s: %m", rlimit_to_string(which_failed));
+
         pid = raw_clone(SIGCHLD|CLONE_NEWNS|
                         arg_clone_ns_flags |
                         (arg_userns_mode != USER_NAMESPACE_NO ? CLONE_NEWUSER : 0));
@@ -3041,79 +3174,14 @@ static int setup_sd_notify_parent(sd_event *event, int fd, pid_t *inner_child_pi
         return 0;
 }
 
-static int load_settings(void) {
-        _cleanup_(settings_freep) Settings *settings = NULL;
-        _cleanup_fclose_ FILE *f = NULL;
-        _cleanup_free_ char *p = NULL;
-        const char *fn, *i;
-        int r;
-
-        /* If all settings are masked, there's no point in looking for
-         * the settings file */
-        if ((arg_settings_mask & _SETTINGS_MASK_ALL) == _SETTINGS_MASK_ALL)
-                return 0;
+static int merge_settings(Settings *settings, const char *path) {
+        int rl;
 
-        fn = strjoina(arg_machine, ".nspawn");
+        assert(settings);
+        assert(path);
 
-        /* We first look in the admin's directories in /etc and /run */
-        FOREACH_STRING(i, "/etc/systemd/nspawn", "/run/systemd/nspawn") {
-                _cleanup_free_ char *j = NULL;
-
-                j = strjoin(i, "/", fn);
-                if (!j)
-                        return log_oom();
-
-                f = fopen(j, "re");
-                if (f) {
-                        p = TAKE_PTR(j);
-
-                        /* By default, we trust configuration from /etc and /run */
-                        if (arg_settings_trusted < 0)
-                                arg_settings_trusted = true;
-
-                        break;
-                }
-
-                if (errno != ENOENT)
-                        return log_error_errno(errno, "Failed to open %s: %m", j);
-        }
-
-        if (!f) {
-                /* After that, let's look for a file next to the
-                 * actual image we shall boot. */
-
-                if (arg_image) {
-                        p = file_in_same_dir(arg_image, fn);
-                        if (!p)
-                                return log_oom();
-                } else if (arg_directory) {
-                        p = file_in_same_dir(arg_directory, fn);
-                        if (!p)
-                                return log_oom();
-                }
-
-                if (p) {
-                        f = fopen(p, "re");
-                        if (!f && errno != ENOENT)
-                                return log_error_errno(errno, "Failed to open %s: %m", p);
-
-                        /* By default, we do not trust configuration from /var/lib/machines */
-                        if (arg_settings_trusted < 0)
-                                arg_settings_trusted = false;
-                }
-        }
-
-        if (!f)
-                return 0;
-
-        log_debug("Settings are trusted: %s", yes_no(arg_settings_trusted));
-
-        r = settings_load(f, p, &settings);
-        if (r < 0)
-                return r;
-
-        /* Copy over bits from the settings, unless they have been
-         * explicitly masked by command line switches. */
+        /* Copy over bits from the settings, unless they have been explicitly masked by command line switches. Note
+         * that this steals the fields of the Settings* structure, and hence modifies it. */
 
         if ((arg_settings_mask & SETTING_START_MODE) == 0 &&
             settings->start_mode >= 0) {
@@ -3148,7 +3216,7 @@ static int load_settings(void) {
 
                 if (!arg_settings_trusted && plus != 0) {
                         if (settings->capability != 0)
-                                log_warning("Ignoring Capability= setting, file %s is not trusted.", p);
+                                log_warning("Ignoring Capability= setting, file %s is not trusted.", path);
                 } else
                         arg_caps_retain |= plus;
 
@@ -3167,7 +3235,7 @@ static int load_settings(void) {
             !sd_id128_is_null(settings->machine_id)) {
 
                 if (!arg_settings_trusted)
-                        log_warning("Ignoring MachineID= setting, file %s is not trusted.", p);
+                        log_warning("Ignoring MachineID= setting, file %s is not trusted.", path);
                 else
                         arg_uuid = settings->machine_id;
         }
@@ -3184,7 +3252,7 @@ static int load_settings(void) {
             settings->n_custom_mounts > 0) {
 
                 if (!arg_settings_trusted)
-                        log_warning("Ignoring TemporaryFileSystem=, Bind= and BindReadOnly= settings, file %s is not trusted.", p);
+                        log_warning("Ignoring TemporaryFileSystem=, Bind= and BindReadOnly= settings, file %s is not trusted.", path);
                 else {
                         custom_mount_free_all(arg_custom_mounts, arg_n_custom_mounts);
                         arg_custom_mounts = TAKE_PTR(settings->custom_mounts);
@@ -3204,7 +3272,7 @@ static int load_settings(void) {
              settings->network_veth_extra)) {
 
                 if (!arg_settings_trusted)
-                        log_warning("Ignoring network settings, file %s is not trusted.", p);
+                        log_warning("Ignoring network settings, file %s is not trusted.", path);
                 else {
                         arg_network_veth = settings_network_veth(settings);
                         arg_private_network = settings_private_network(settings);
@@ -3223,7 +3291,7 @@ static int load_settings(void) {
             settings->expose_ports) {
 
                 if (!arg_settings_trusted)
-                        log_warning("Ignoring Port= setting, file %s is not trusted.", p);
+                        log_warning("Ignoring Port= setting, file %s is not trusted.", path);
                 else {
                         expose_port_free_all(arg_expose_ports);
                         arg_expose_ports = TAKE_PTR(settings->expose_ports);
@@ -3234,7 +3302,7 @@ static int load_settings(void) {
             settings->userns_mode != _USER_NAMESPACE_MODE_INVALID) {
 
                 if (!arg_settings_trusted)
-                        log_warning("Ignoring PrivateUsers= and PrivateUsersChown= settings, file %s is not trusted.", p);
+                        log_warning("Ignoring PrivateUsers= and PrivateUsersChown= settings, file %s is not trusted.", path);
                 else {
                         arg_userns_mode = settings->userns_mode;
                         arg_uid_shift = settings->uid_shift;
@@ -3249,16 +3317,137 @@ static int load_settings(void) {
         if ((arg_settings_mask & SETTING_SYSCALL_FILTER) == 0) {
 
                 if (!arg_settings_trusted && !strv_isempty(arg_syscall_whitelist))
-                        log_warning("Ignoring SystemCallFilter= settings, file %s is not trusted.", p);
+                        log_warning("Ignoring SystemCallFilter= settings, file %s is not trusted.", path);
                 else {
                         strv_free_and_replace(arg_syscall_whitelist, settings->syscall_whitelist);
                         strv_free_and_replace(arg_syscall_blacklist, settings->syscall_blacklist);
                 }
         }
 
+        for (rl = 0; rl < _RLIMIT_MAX; rl ++) {
+                if ((arg_settings_mask & (SETTING_RLIMIT_FIRST << rl)))
+                        continue;
+
+                if (!settings->rlimit[rl])
+                        continue;
+
+                if (!arg_settings_trusted) {
+                        log_warning("Ignoring Limit%s= setting, file '%s' is not trusted.", rlimit_to_string(rl), path);
+                        continue;
+                }
+
+                free_and_replace(arg_rlimit[rl], settings->rlimit[rl]);
+        }
+
+        if ((arg_settings_mask & SETTING_HOSTNAME) == 0 &&
+            settings->hostname)
+                free_and_replace(arg_hostname, settings->hostname);
+
+        if ((arg_settings_mask & SETTING_NO_NEW_PRIVILEGES) == 0 &&
+            settings->no_new_privileges >= 0)
+                arg_no_new_privileges = settings->no_new_privileges;
+
+        if ((arg_settings_mask & SETTING_OOM_SCORE_ADJUST) == 0 &&
+            settings->oom_score_adjust_set) {
+
+                if (!arg_settings_trusted)
+                        log_warning("Ignoring OOMScoreAdjust= setting, file '%s' is not trusted.", path);
+                else {
+                        arg_oom_score_adjust = settings->oom_score_adjust;
+                        arg_oom_score_adjust_set = true;
+                }
+        }
+
+        if ((arg_settings_mask & SETTING_CPU_AFFINITY) == 0 &&
+            settings->cpuset) {
+
+                if (!arg_settings_trusted)
+                        log_warning("Ignoring CPUAffinity= setting, file '%s' is not trusted.", path);
+                else {
+                        if (arg_cpuset)
+                                CPU_FREE(arg_cpuset);
+                        arg_cpuset = TAKE_PTR(settings->cpuset);
+                        arg_cpuset_ncpus = settings->cpuset_ncpus;
+                }
+        }
+
         return 0;
 }
 
+static int load_settings(void) {
+        _cleanup_(settings_freep) Settings *settings = NULL;
+        _cleanup_fclose_ FILE *f = NULL;
+        _cleanup_free_ char *p = NULL;
+        const char *fn, *i;
+        int r;
+
+        /* If all settings are masked, there's no point in looking for
+         * the settings file */
+        if ((arg_settings_mask & _SETTINGS_MASK_ALL) == _SETTINGS_MASK_ALL)
+                return 0;
+
+        fn = strjoina(arg_machine, ".nspawn");
+
+        /* We first look in the admin's directories in /etc and /run */
+        FOREACH_STRING(i, "/etc/systemd/nspawn", "/run/systemd/nspawn") {
+                _cleanup_free_ char *j = NULL;
+
+                j = strjoin(i, "/", fn);
+                if (!j)
+                        return log_oom();
+
+                f = fopen(j, "re");
+                if (f) {
+                        p = TAKE_PTR(j);
+
+                        /* By default, we trust configuration from /etc and /run */
+                        if (arg_settings_trusted < 0)
+                                arg_settings_trusted = true;
+
+                        break;
+                }
+
+                if (errno != ENOENT)
+                        return log_error_errno(errno, "Failed to open %s: %m", j);
+        }
+
+        if (!f) {
+                /* After that, let's look for a file next to the
+                 * actual image we shall boot. */
+
+                if (arg_image) {
+                        p = file_in_same_dir(arg_image, fn);
+                        if (!p)
+                                return log_oom();
+                } else if (arg_directory) {
+                        p = file_in_same_dir(arg_directory, fn);
+                        if (!p)
+                                return log_oom();
+                }
+
+                if (p) {
+                        f = fopen(p, "re");
+                        if (!f && errno != ENOENT)
+                                return log_error_errno(errno, "Failed to open %s: %m", p);
+
+                        /* By default, we do not trust configuration from /var/lib/machines */
+                        if (arg_settings_trusted < 0)
+                                arg_settings_trusted = false;
+                }
+        }
+
+        if (!f)
+                return 0;
+
+        log_debug("Settings are trusted: %s", yes_no(arg_settings_trusted));
+
+        r = settings_load(f, p, &settings);
+        if (r < 0)
+                return r;
+
+        return merge_settings(settings, p);
+}
+
 static int run(int master,
                const char* console,
                DissectedImage *dissected_image,
@@ -3680,20 +3869,20 @@ static int run(int master,
                    "STATUS=Container running.\n"
                    "X_NSPAWN_LEADER_PID=" PID_FMT, *pid);
         if (!arg_notify_ready)
-                sd_notify(false, "READY=1\n");
+                (void) sd_notify(false, "READY=1\n");
 
         if (arg_kill_signal > 0) {
                 /* Try to kill the init system on SIGINT or SIGTERM */
-                sd_event_add_signal(event, NULL, SIGINT, on_orderly_shutdown, PID_TO_PTR(*pid));
-                sd_event_add_signal(event, NULL, SIGTERM, on_orderly_shutdown, PID_TO_PTR(*pid));
+                (void) sd_event_add_signal(event, NULL, SIGINT, on_orderly_shutdown, PID_TO_PTR(*pid));
+                (void) sd_event_add_signal(event, NULL, SIGTERM, on_orderly_shutdown, PID_TO_PTR(*pid));
         } else {
                 /* Immediately exit */
-                sd_event_add_signal(event, NULL, SIGINT, NULL, NULL);
-                sd_event_add_signal(event, NULL, SIGTERM, NULL, NULL);
+                (void) sd_event_add_signal(event, NULL, SIGINT, NULL, NULL);
+                (void) sd_event_add_signal(event, NULL, SIGTERM, NULL, NULL);
         }
 
         /* Exit when the child exits */
-        sd_event_add_signal(event, NULL, SIGCHLD, on_sigchld, PID_TO_PTR(*pid));
+        (void) sd_event_add_signal(event, NULL, SIGCHLD, on_sigchld, PID_TO_PTR(*pid));
 
         if (arg_expose_ports) {
                 r = expose_port_watch_rtnl(event, rtnl_socket_pair[0], on_address_change, exposed, &rtnl);
@@ -3767,6 +3956,71 @@ static int run(int master,
         return 1; /* loop again */
 }
 
+static int initialize_rlimits(void) {
+
+        /* The default resource limits the kernel passes to PID 1, as per kernel 4.16. Let's pass our container payload
+         * the same values as the kernel originally passed to PID 1, in order to minimize differences between host and
+         * container execution environments. */
+
+        static const struct rlimit kernel_defaults[_RLIMIT_MAX] = {
+                [RLIMIT_AS]       = { RLIM_INFINITY, RLIM_INFINITY },
+                [RLIMIT_CORE]     = { 0,             RLIM_INFINITY },
+                [RLIMIT_CPU]      = { RLIM_INFINITY, RLIM_INFINITY },
+                [RLIMIT_DATA]     = { RLIM_INFINITY, RLIM_INFINITY },
+                [RLIMIT_FSIZE]    = { RLIM_INFINITY, RLIM_INFINITY },
+                [RLIMIT_LOCKS]    = { RLIM_INFINITY, RLIM_INFINITY },
+                [RLIMIT_MEMLOCK]  = { 65536,         65536         },
+                [RLIMIT_MSGQUEUE] = { 819200,        819200        },
+                [RLIMIT_NICE]     = { 0,             0             },
+                [RLIMIT_NOFILE]   = { 1024,          4096          },
+                [RLIMIT_RSS]      = { RLIM_INFINITY, RLIM_INFINITY },
+                [RLIMIT_RTPRIO]   = { 0,             0             },
+                [RLIMIT_RTTIME]   = { RLIM_INFINITY, RLIM_INFINITY },
+                [RLIMIT_STACK]    = { 8388608,       RLIM_INFINITY },
+
+                /* The kernel scales the default for RLIMIT_NPROC and RLIMIT_SIGPENDING based on the system's amount of
+                 * RAM. To provide best compatibility we'll read these limits off PID 1 instead of hardcoding them
+                 * here. This is safe as we know that PID 1 doesn't change these two limits and thus the original
+                 * kernel's initialization should still be valid during runtime — at least if PID 1 is systemd. Note
+                 * that PID 1 changes a number of other resource limits during early initialization which is why we
+                 * don't read the other limits from PID 1 but prefer the static table above. */
+        };
+
+        int rl;
+
+        for (rl = 0; rl < _RLIMIT_MAX; rl++) {
+
+                /* Let's only fill in what the user hasn't explicitly configured anyway */
+                if ((arg_settings_mask & (SETTING_RLIMIT_FIRST << rl)) == 0) {
+                        const struct rlimit *v;
+                        struct rlimit buffer;
+
+                        if (IN_SET(rl, RLIMIT_NPROC, RLIMIT_SIGPENDING)) {
+                                /* For these two let's read the limits off PID 1. See above for an explanation. */
+
+                                if (prlimit(1, rl, NULL, &buffer) < 0)
+                                        return log_error_errno(errno, "Failed to read resource limit RLIMIT_%s of PID 1: %m", rlimit_to_string(rl));
+
+                                v = &buffer;
+                        } else
+                                v = kernel_defaults + rl;
+
+                        arg_rlimit[rl] = newdup(struct rlimit, v, 1);
+                        if (!arg_rlimit[rl])
+                                return log_oom();
+                }
+
+                if (DEBUG_LOGGING) {
+                        _cleanup_free_ char *k = NULL;
+
+                        (void) rlimit_format(arg_rlimit[rl], &k);
+                        log_debug("Setting RLIMIT_%s to %s.", rlimit_to_string(rl), k);
+                }
+        }
+
+        return 0;
+}
+
 int main(int argc, char *argv[]) {
 
         _cleanup_free_ char *console = NULL;
@@ -3799,6 +4053,10 @@ int main(int argc, char *argv[]) {
         if (r < 0)
                 goto finish;
 
+        r = initialize_rlimits();
+        if (r < 0)
+                goto finish;
+
         r = determine_names();
         if (r < 0)
                 goto finish;
@@ -4077,7 +4335,7 @@ int main(int argc, char *argv[]) {
 
         assert_se(sigprocmask_many(SIG_BLOCK, NULL, SIGCHLD, SIGWINCH, SIGTERM, SIGINT, -1) >= 0);
 
-        if (prctl(PR_SET_CHILD_SUBREAPER, 1) < 0) {
+        if (prctl(PR_SET_CHILD_SUBREAPER, 1, 0, 0, 0) < 0) {
                 r = log_error_errno(errno, "Failed to become subreaper: %m");
                 goto finish;
         }
@@ -4112,6 +4370,8 @@ finish:
         if (pid > 0)
                 (void) wait_for_terminate(pid, NULL);
 
+        pager_close();
+
         if (remove_directory && arg_directory) {
                 int k;
 
@@ -4147,6 +4407,7 @@ finish:
         free(arg_template);
         free(arg_image);
         free(arg_machine);
+        free(arg_hostname);
         free(arg_user);
         free(arg_pivot_root_new);
         free(arg_pivot_root_old);
@@ -4161,6 +4422,8 @@ finish:
         custom_mount_free_all(arg_custom_mounts, arg_n_custom_mounts);
         expose_port_free_all(arg_expose_ports);
         free(arg_root_hash);
+        rlimit_free_all(arg_rlimit);
+        arg_cpuset = cpu_set_mfree(arg_cpuset);
 
         return r < 0 ? EXIT_FAILURE : ret;
 }
index be978dd3bb200ee8cab9ea3b14da2aeb486c6f3e..0060a1caba7a704f5b8bea34308e6b83fb2820db 100644 (file)
@@ -1438,40 +1438,6 @@ static int bus_property_get_dnssec_statistics(
                                      (uint64_t) m->n_dnssec_verdict[DNSSEC_INDETERMINATE]);
 }
 
-static int bus_property_get_dnssec_supported(
-                sd_bus *bus,
-                const char *path,
-                const char *interface,
-                const char *property,
-                sd_bus_message *reply,
-                void *userdata,
-                sd_bus_error *error) {
-
-        Manager *m = userdata;
-
-        assert(reply);
-        assert(m);
-
-        return sd_bus_message_append(reply, "b", manager_dnssec_supported(m));
-}
-
-static int bus_property_get_dnssec_mode(
-                sd_bus *bus,
-                const char *path,
-                const char *interface,
-                const char *property,
-                sd_bus_message *reply,
-                void *userdata,
-                sd_bus_error *error) {
-
-        Manager *m = userdata;
-
-        assert(reply);
-        assert(m);
-
-        return sd_bus_message_append(reply, "s", dnssec_mode_to_string(manager_get_dnssec_mode(m)));
-}
-
 static int bus_property_get_ntas(
                 sd_bus *bus,
                 const char *path,
@@ -1503,6 +1469,8 @@ static int bus_property_get_ntas(
 }
 
 static BUS_DEFINE_PROPERTY_GET_ENUM(bus_property_get_dns_stub_listener_mode, dns_stub_listener_mode, DnsStubListenerMode);
+static BUS_DEFINE_PROPERTY_GET(bus_property_get_dnssec_supported, "b", Manager, manager_dnssec_supported);
+static BUS_DEFINE_PROPERTY_GET2(bus_property_get_dnssec_mode, "s", Manager, manager_get_dnssec_mode, dnssec_mode_to_string);
 
 static int bus_method_reset_statistics(sd_bus_message *message, void *userdata, sd_bus_error *error) {
         Manager *m = userdata;
index ceaf71a71d539b82f914ac910066504e8c182b64..a1fc3ad9d5a6ae41418df9efc0f22502fd20737f 100644 (file)
 #include "resolved-resolv-conf.h"
 #include "strv.h"
 
-static int property_get_dnssec_mode(
-                sd_bus *bus,
-                const char *path,
-                const char *interface,
-                const char *property,
-                sd_bus_message *reply,
-                void *userdata,
-                sd_bus_error *error) {
-
-        Link *l = userdata;
-
-        assert(reply);
-        assert(l);
-
-        return sd_bus_message_append(reply, "s", dnssec_mode_to_string(link_get_dnssec_mode(l)));
-}
+static BUS_DEFINE_PROPERTY_GET(property_get_dnssec_supported, "b", Link, link_dnssec_supported);
+static BUS_DEFINE_PROPERTY_GET2(property_get_dnssec_mode, "s", Link, link_get_dnssec_mode, dnssec_mode_to_string);
 
 static int property_get_dns(
                 sd_bus *bus,
@@ -163,23 +149,6 @@ static int property_get_ntas(
         return sd_bus_message_close_container(reply);
 }
 
-static int property_get_dnssec_supported(
-                sd_bus *bus,
-                const char *path,
-                const char *interface,
-                const char *property,
-                sd_bus_message *reply,
-                void *userdata,
-                sd_bus_error *error) {
-
-        Link *l = userdata;
-
-        assert(reply);
-        assert(l);
-
-        return sd_bus_message_append(reply, "b", link_dnssec_supported(l));
-}
-
 static int verify_unmanaged_link(Link *l, sd_bus_error *error) {
         assert(l);
 
index 78d5141053dbe4cff35f19798eb6e125a6a0d6c4..fc035e796ebd24c94b0818de066a1d98dbe80961 100644 (file)
@@ -684,7 +684,8 @@ static int bus_append_automount_property(sd_bus_message *m, const char *field, c
 }
 
 static int bus_append_execute_property(sd_bus_message *m, const char *field, const char *eq) {
-        int r, rl;
+        const char *suffix;
+        int r;
 
         if (STR_IN_SET(field,
                        "User", "Group",
@@ -863,25 +864,29 @@ static int bus_append_execute_property(sd_bus_message *m, const char *field, con
                 return bus_append_byte_array(m, field, decoded, sz);
         }
 
-        rl = rlimit_from_string(field);
-        if (rl >= 0) {
-                const char *sn;
-                struct rlimit l;
+        if ((suffix = startswith(field, "Limit"))) {
+                int rl;
 
-                r = rlimit_parse(rl, eq, &l);
-                if (r < 0)
-                        return log_error_errno(r, "Failed to parse resource limit: %s", eq);
+                rl = rlimit_from_string(suffix);
+                if (rl >= 0) {
+                        const char *sn;
+                        struct rlimit l;
 
-                r = sd_bus_message_append(m, "(sv)", field, "t", l.rlim_max);
-                if (r < 0)
-                        return bus_log_create_error(r);
+                        r = rlimit_parse(rl, eq, &l);
+                        if (r < 0)
+                                return log_error_errno(r, "Failed to parse resource limit: %s", eq);
 
-                sn = strjoina(field, "Soft");
-                r = sd_bus_message_append(m, "(sv)", sn, "t", l.rlim_cur);
-                if (r < 0)
-                        return bus_log_create_error(r);
+                        r = sd_bus_message_append(m, "(sv)", field, "t", l.rlim_max);
+                        if (r < 0)
+                                return bus_log_create_error(r);
 
-                return 1;
+                        sn = strjoina(field, "Soft");
+                        r = sd_bus_message_append(m, "(sv)", sn, "t", l.rlim_cur);
+                        if (r < 0)
+                                return bus_log_create_error(r);
+
+                        return 1;
+                }
         }
 
         if (STR_IN_SET(field, "AppArmorProfile", "SmackProcessLabel")) {
index 66724d0e7841c2eac75c98c0d52d6b7b609a2dc9..c80fc4fcbb6c0c6f39930758fe7bba12355b6aee 100644 (file)
@@ -1613,36 +1613,40 @@ int bus_property_get_rlimit(
                 void *userdata,
                 sd_bus_error *error) {
 
+        const char *is_soft;
         struct rlimit *rl;
         uint64_t u;
         rlim_t x;
-        const char *is_soft;
 
         assert(bus);
         assert(reply);
         assert(userdata);
 
         is_soft = endswith(property, "Soft");
+
         rl = *(struct rlimit**) userdata;
         if (rl)
                 x = is_soft ? rl->rlim_cur : rl->rlim_max;
         else {
                 struct rlimit buf = {};
+                const char *s, *p;
                 int z;
-                const char *s;
 
+                /* Chop off "Soft" suffix */
                 s = is_soft ? strndupa(property, is_soft - property) : property;
 
-                z = rlimit_from_string(strstr(s, "Limit"));
+                /* Skip over any prefix, such as "Default" */
+                assert_se(p = strstr(s, "Limit"));
+
+                z = rlimit_from_string(p + 5);
                 assert(z >= 0);
 
-                getrlimit(z, &buf);
+                (void) getrlimit(z, &buf);
                 x = is_soft ? buf.rlim_cur : buf.rlim_max;
         }
 
-        /* rlim_t might have different sizes, let's map
-         * RLIMIT_INFINITY to (uint64_t) -1, so that it is the same on
-         * all archs */
+        /* rlim_t might have different sizes, let's map RLIMIT_INFINITY to (uint64_t) -1, so that it is the same on all
+         * archs */
         u = x == RLIM_INFINITY ? (uint64_t) -1 : (uint64_t) x;
 
         return sd_bus_message_append(reply, "t", u);
index 74526c5e8b234b312ee2b4565173af014ee2da6f..a3af8d8fbccc117eafd5be8c08d2691720fde388 100644 (file)
@@ -157,34 +157,15 @@ int bus_log_create_error(int r);
         }
 
 #define ident(x) (x)
-#define BUS_DEFINE_PROPERTY_GET(function, bus_type, data_type, get1)    \
+#define BUS_DEFINE_PROPERTY_GET(function, bus_type, data_type, get1) \
         BUS_DEFINE_PROPERTY_GET2(function, bus_type, data_type, get1, ident)
 
+#define ref(x) (*(x))
+#define BUS_DEFINE_PROPERTY_GET_REF(function, bus_type, data_type, get) \
+        BUS_DEFINE_PROPERTY_GET2(function, bus_type, data_type, ref, get)
+
 #define BUS_DEFINE_PROPERTY_GET_ENUM(function, name, type)              \
-        int function(sd_bus *bus,                                       \
-                     const char *path,                                  \
-                     const char *interface,                             \
-                     const char *property,                              \
-                     sd_bus_message *reply,                             \
-                     void *userdata,                                    \
-                     sd_bus_error *error) {                             \
-                                                                        \
-                const char *value;                                      \
-                type *field = userdata;                                 \
-                int r;                                                  \
-                                                                        \
-                assert(bus);                                            \
-                assert(reply);                                          \
-                assert(field);                                          \
-                                                                        \
-                value = strempty(name##_to_string(*field));             \
-                                                                        \
-                r = sd_bus_message_append_basic(reply, 's', value);     \
-                if (r < 0)                                              \
-                        return r;                                       \
-                                                                        \
-                return 1;                                               \
-        }
+        BUS_DEFINE_PROPERTY_GET_REF(function, "s", type, name##_to_string)
 
 #define BUS_PROPERTY_DUAL_TIMESTAMP(name, offset, flags) \
         SD_BUS_PROPERTY(name, "t", bus_property_get_usec, (offset) + offsetof(struct dual_timestamp, realtime), (flags)), \
index 9b822dd49a926edd87b7dd56a8134d0ce9c20b99..84d0c16996ed0a912a6b083ae74dcee223428dca 100644 (file)
@@ -33,6 +33,7 @@
 #include "syslog-util.h"
 #include "time-util.h"
 #include "utf8.h"
+#include "rlimit-util.h"
 
 int config_item_table_lookup(
                 const void *table,
@@ -707,7 +708,7 @@ int config_parse_string(
                 void *data,
                 void *userdata) {
 
-        char **s = data, *n;
+        char **s = data;
 
         assert(filename);
         assert(lvalue);
@@ -719,16 +720,8 @@ int config_parse_string(
                 return 0;
         }
 
-        if (isempty(rvalue))
-                n = NULL;
-        else {
-                n = strdup(rvalue);
-                if (!n)
-                        return log_oom();
-        }
-
-        free(*s);
-        *s = n;
+        if (free_and_strdup(s, empty_to_null(rvalue)) < 0)
+                return log_oom();
 
         return 0;
 }
@@ -1214,3 +1207,42 @@ int config_parse_mtu(
 
         return 0;
 }
+
+int config_parse_rlimit(
+                const char *unit,
+                const char *filename,
+                unsigned line,
+                const char *section,
+                unsigned section_line,
+                const char *lvalue,
+                int ltype,
+                const char *rvalue,
+                void *data,
+                void *userdata) {
+
+        struct rlimit **rl = data, d = {};
+        int r;
+
+        assert(rvalue);
+        assert(rl);
+
+        r = rlimit_parse(ltype, rvalue, &d);
+        if (r == -EILSEQ) {
+                log_syntax(unit, LOG_WARNING, filename, line, r, "Soft resource limit chosen higher than hard limit, ignoring: %s", rvalue);
+                return 0;
+        }
+        if (r < 0) {
+                log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse resource value, ignoring: %s", rvalue);
+                return 0;
+        }
+
+        if (rl[ltype])
+                *rl[ltype] = d;
+        else {
+                rl[ltype] = newdup(struct rlimit, &d, 1);
+                if (!rl[ltype])
+                        return log_oom();
+        }
+
+        return 0;
+}
index 094b9cbc447467d2126edb387fb94fbcb108a52e..76adc9a88eca7baadf91daa72f7d2bf3622050f2 100644 (file)
@@ -147,6 +147,7 @@ int config_parse_ifname(GENERIC_PARSER_ARGS);
 int config_parse_ip_port(GENERIC_PARSER_ARGS);
 int config_parse_join_controllers(GENERIC_PARSER_ARGS);
 int config_parse_mtu(GENERIC_PARSER_ARGS);
+int config_parse_rlimit(GENERIC_PARSER_ARGS);
 
 typedef enum Disabled {
         DISABLED_CONFIGURATION,
index 92e5851519f4d0c247fcfdb60a73a122e3f49bc5..af041d2f74bb3f5ba6771d0ff5219a16415652fb 100644 (file)
@@ -1746,7 +1746,6 @@ static void free_database(Hashmap *by_name, Hashmap *by_id) {
 
 static int cat_config(void) {
         _cleanup_strv_free_ char **files = NULL;
-        _cleanup_free_ char *replace_file = NULL;
         int r;
 
         r = conf_files_list_with_replacement(arg_root, CONF_PATHS_STRV("sysusers.d"), arg_replace, &files, NULL);
index 90ec20378f6f313b4852e48ab63f52ea1da50bd0..d569bdd85fafe99d4e27e8977db408378528f1c3 100644 (file)
@@ -8,6 +8,7 @@
 #include "conf-parser.h"
 #include "fd-util.h"
 #include "fileio.h"
+#include "fs-util.h"
 #include "log.h"
 #include "macro.h"
 #include "string-util.h"
@@ -313,7 +314,7 @@ static const char* const config_file[] = {
 };
 
 static void test_config_parse(unsigned i, const char *s) {
-        char name[] = "/tmp/test-conf-parser.XXXXXX";
+        _cleanup_(unlink_tempfilep) char name[] = "/tmp/test-conf-parser.XXXXXX";
         int fd, r;
         _cleanup_fclose_ FILE *f = NULL;
         _cleanup_free_ char *setting1 = NULL;
index 730dfd1e0b838f3cff238cdc6b26a4aed1178a57..20202c9421c31b64491a40c6e2712866bd0466df 100644 (file)
@@ -24,6 +24,7 @@
 #if HAVE_SECCOMP
 #include "seccomp-util.h"
 #endif
+#include "service.h"
 #include "stat-util.h"
 #include "test-helper.h"
 #include "tests.h"
index 2ae954c2f26a40a68bf838c01ed729a980742b8b..bbddbf3bcdae7c289e55a637a24e4a7002d73e10 100644 (file)
@@ -15,6 +15,7 @@
 #include "env-util.h"
 #include "fd-util.h"
 #include "fileio.h"
+#include "fs-util.h"
 #include "io-util.h"
 #include "parse-util.h"
 #include "process-util.h"
@@ -23,7 +24,8 @@
 #include "util.h"
 
 static void test_parse_env_file(void) {
-        char    t[] = "/tmp/test-fileio-in-XXXXXX",
+        _cleanup_(unlink_tempfilep) char
+                t[] = "/tmp/test-fileio-in-XXXXXX",
                 p[] = "/tmp/test-fileio-out-XXXXXX";
         int fd, r;
         FILE *f;
@@ -135,13 +137,11 @@ static void test_parse_env_file(void) {
 
         r = load_env_file(NULL, p, NULL, &b);
         assert_se(r >= 0);
-
-        unlink(t);
-        unlink(p);
 }
 
 static void test_parse_multiline_env_file(void) {
-        char    t[] = "/tmp/test-fileio-in-XXXXXX",
+        _cleanup_(unlink_tempfilep) char
+                t[] = "/tmp/test-fileio-in-XXXXXX",
                 p[] = "/tmp/test-fileio-out-XXXXXX";
         int fd, r;
         FILE *f;
@@ -189,13 +189,10 @@ static void test_parse_multiline_env_file(void) {
 
         r = load_env_file(NULL, p, NULL, &b);
         assert_se(r >= 0);
-
-        unlink(t);
-        unlink(p);
 }
 
 static void test_merge_env_file(void) {
-        char t[] = "/tmp/test-fileio-XXXXXX";
+        _cleanup_(unlink_tempfilep) char t[] = "/tmp/test-fileio-XXXXXX";
         int fd, r;
         _cleanup_fclose_ FILE *f = NULL;
         _cleanup_strv_free_ char **a = NULL;
@@ -264,7 +261,7 @@ static void test_merge_env_file(void) {
 }
 
 static void test_merge_env_file_invalid(void) {
-        char t[] = "/tmp/test-fileio-XXXXXX";
+        _cleanup_(unlink_tempfilep) char t[] = "/tmp/test-fileio-XXXXXX";
         int fd, r;
         _cleanup_fclose_ FILE *f = NULL;
         _cleanup_strv_free_ char **a = NULL;
@@ -303,9 +300,9 @@ static void test_merge_env_file_invalid(void) {
 }
 
 static void test_executable_is_script(void) {
-        char t[] = "/tmp/test-executable-XXXXXX";
+        _cleanup_(unlink_tempfilep) char t[] = "/tmp/test-fileio-XXXXXX";
         int fd, r;
-        FILE *f;
+        _cleanup_fclose_ FILE *f = NULL;
         char *command;
 
         fd = mkostemp_safe(t);
@@ -331,9 +328,6 @@ static void test_executable_is_script(void) {
                 assert_se(startswith(command, "/"));
                 free(command);
         }
-
-        fclose(f);
-        unlink(t);
 }
 
 static void test_status_field(void) {
@@ -392,8 +386,8 @@ static void test_capeff(void) {
 }
 
 static void test_write_string_stream(void) {
-        char fn[] = "/tmp/test-write_string_stream-XXXXXX";
-        FILE *f = NULL;
+        _cleanup_(unlink_tempfilep) char fn[] = "/tmp/test-write_string_stream-XXXXXX";
+        _cleanup_fclose_ FILE *f = NULL;
         int fd;
         char buf[64];
 
@@ -424,13 +418,10 @@ static void test_write_string_stream(void) {
         assert_se(fgets(buf, sizeof(buf), f));
         printf(">%s<", buf);
         assert_se(streq(buf, "boohoo"));
-        f = safe_fclose(f);
-
-        unlink(fn);
 }
 
 static void test_write_string_file(void) {
-        char fn[] = "/tmp/test-write_string_file-XXXXXX";
+        _cleanup_(unlink_tempfilep) char fn[] = "/tmp/test-write_string_file-XXXXXX";
         char buf[64] = {};
         _cleanup_close_ int fd;
 
@@ -441,12 +432,10 @@ static void test_write_string_file(void) {
 
         assert_se(read(fd, buf, sizeof(buf)) == 7);
         assert_se(streq(buf, "boohoo\n"));
-
-        unlink(fn);
 }
 
 static void test_write_string_file_no_create(void) {
-        char fn[] = "/tmp/test-write_string_file_no_create-XXXXXX";
+        _cleanup_(unlink_tempfilep) char fn[] = "/tmp/test-write_string_file_no_create-XXXXXX";
         _cleanup_close_ int fd;
         char buf[64] = {0};
 
@@ -458,8 +447,6 @@ static void test_write_string_file_no_create(void) {
 
         assert_se(read(fd, buf, sizeof(buf)) == STRLEN("boohoo\n"));
         assert_se(streq(buf, "boohoo\n"));
-
-        unlink(fn);
 }
 
 static void test_write_string_file_verify(void) {
@@ -483,9 +470,8 @@ static void test_write_string_file_verify(void) {
 }
 
 static void test_load_env_file_pairs(void) {
-        char fn[] = "/tmp/test-load_env_file_pairs-XXXXXX";
-        int fd;
-        int r;
+        _cleanup_(unlink_tempfilep) char fn[] = "/tmp/test-load_env_file_pairs-XXXXXX";
+        int fd, r;
         _cleanup_fclose_ FILE *f = NULL;
         _cleanup_strv_free_ char **l = NULL;
         char **k, **v;
@@ -522,15 +508,13 @@ static void test_load_env_file_pairs(void) {
                 if (streq(*k, "SUPPORT_URL")) assert_se(streq(*v, "https://bbs.archlinux.org/"));
                 if (streq(*k, "BUG_REPORT_URL")) assert_se(streq(*v, "https://bugs.archlinux.org/"));
         }
-
-        unlink(fn);
 }
 
 static void test_search_and_fopen(void) {
         const char *dirs[] = {"/tmp/foo/bar", "/tmp", NULL};
+
         char name[] = "/tmp/test-search_and_fopen.XXXXXX";
-        int fd = -1;
-        int r;
+        int fd, r;
         FILE *f;
 
         fd = mkostemp_safe(name);
@@ -563,9 +547,9 @@ static void test_search_and_fopen(void) {
 
 static void test_search_and_fopen_nulstr(void) {
         const char dirs[] = "/tmp/foo/bar\0/tmp\0";
-        char name[] = "/tmp/test-search_and_fopen.XXXXXX";
-        int fd = -1;
-        int r;
+
+        _cleanup_(unlink_tempfilep) char name[] = "/tmp/test-search_and_fopen.XXXXXX";
+        int fd, r;
         FILE *f;
 
         fd = mkostemp_safe(name);
@@ -593,12 +577,12 @@ static void test_search_and_fopen_nulstr(void) {
 }
 
 static void test_writing_tmpfile(void) {
-        char name[] = "/tmp/test-systemd_writing_tmpfile.XXXXXX";
+        _cleanup_(unlink_tempfilep) char name[] = "/tmp/test-systemd_writing_tmpfile.XXXXXX";
         _cleanup_free_ char *contents = NULL;
         size_t size;
-        int r;
         _cleanup_close_ int fd = -1;
         struct iovec iov[3];
+        int r;
 
         iov[0] = IOVEC_MAKE_STRING("abc\n");
         iov[1] = IOVEC_MAKE_STRING(ALPHANUMERICAL "\n");
@@ -614,8 +598,6 @@ static void test_writing_tmpfile(void) {
         assert_se(r == 0);
         printf("contents: %s", contents);
         assert_se(streq(contents, "abc\n" ALPHANUMERICAL "\n"));
-
-        unlink(name);
 }
 
 static void test_tempfn(void) {
@@ -703,7 +685,7 @@ static void test_read_line(void) {
 }
 
 static void test_read_line2(void) {
-        char name[] = "/tmp/test-fileio.XXXXXX";
+        _cleanup_(unlink_tempfilep) char name[] = "/tmp/test-fileio.XXXXXX";
         int fd;
         _cleanup_fclose_ FILE *f = NULL;
 
index ed53177dcc8ded864c2fd15817502b487dc25f39..cdc2375d563389ae18f2309883daf98d30363fee 100644 (file)
@@ -11,6 +11,7 @@
 #include <sys/types.h>
 
 #include "alloc-util.h"
+#include "all-units.h"
 #include "fd-util.h"
 #include "fs-util.h"
 #include "macro.h"
index 09c35b4f8b27c9a80cded0a12b9ad07c78bd4bd6..38de758cb6ac469dade2cec25562d782abf8965c 100644 (file)
@@ -42,6 +42,7 @@ int main(int argc, char *argv[]) {
                 .rlim_cur = 10,
                 .rlim_max = 5,
         };
+        int i;
 
         log_parse_environment();
         log_open();
@@ -53,10 +54,41 @@ int main(int argc, char *argv[]) {
         new.rlim_max = old.rlim_max;
         assert_se(setrlimit(RLIMIT_NOFILE, &new) >= 0);
 
-        assert_se(rlimit_from_string("LimitNOFILE") == RLIMIT_NOFILE);
+        assert_se(rlimit_from_string("NOFILE") == RLIMIT_NOFILE);
+        assert_se(rlimit_from_string("LimitNOFILE") == -1);
+        assert_se(rlimit_from_string("RLIMIT_NOFILE") == -1);
+        assert_se(rlimit_from_string("xxxNOFILE") == -1);
         assert_se(rlimit_from_string("DefaultLimitNOFILE") == -1);
 
-        assert_se(streq_ptr(rlimit_to_string(RLIMIT_NOFILE), "LimitNOFILE"));
+        assert_se(rlimit_from_string_harder("NOFILE") == RLIMIT_NOFILE);
+        assert_se(rlimit_from_string_harder("LimitNOFILE") == RLIMIT_NOFILE);
+        assert_se(rlimit_from_string_harder("RLIMIT_NOFILE") == RLIMIT_NOFILE);
+        assert_se(rlimit_from_string_harder("xxxNOFILE") == -1);
+        assert_se(rlimit_from_string_harder("DefaultLimitNOFILE") == -1);
+
+        for (i = 0; i < _RLIMIT_MAX; i++) {
+                _cleanup_free_ char *prefixed = NULL;
+                const char *p;
+
+                assert_se(p = rlimit_to_string(i));
+                log_info("%i = %s", i, p);
+
+                assert_se(rlimit_from_string(p) == i);
+                assert_se(rlimit_from_string_harder(p) == i);
+
+                assert_se(prefixed = strjoin("Limit", p));
+
+                assert_se(rlimit_from_string(prefixed) < 0);
+                assert_se(rlimit_from_string_harder(prefixed) == i);
+
+                prefixed = mfree(prefixed);
+                assert_se(prefixed = strjoin("RLIMIT_", p));
+
+                assert_se(rlimit_from_string(prefixed) < 0);
+                assert_se(rlimit_from_string_harder(prefixed) == i);
+        }
+
+        assert_se(streq_ptr(rlimit_to_string(RLIMIT_NOFILE), "NOFILE"));
         assert_se(rlimit_to_string(-1) == NULL);
 
         assert_se(getrlimit(RLIMIT_NOFILE, &old) == 0);
index 7d8fc445ec085087b5d3250b78e00265de96f546..da0f8581423d085bcb7fcb460b9f783b97deb128 100644 (file)
@@ -7,6 +7,7 @@
 
 #include <sched.h>
 
+#include "all-units.h"
 #include "macro.h"
 #include "manager.h"
 #include "rm-rf.h"
index 13db2f4225c5b3be13bfeadf137c1b5ee47c5fc5..7b74ed0dc3ebf09cc89c226e3ca714167f3f6c5f 100644 (file)
 #include <unistd.h>
 
 #include "alloc-util.h"
+#include "all-units.h"
 #include "capability-util.h"
+#include "conf-parser.h"
 #include "fd-util.h"
 #include "fileio.h"
+#include "fs-util.h"
 #include "hashmap.h"
 #include "hostname-util.h"
 #include "install-printf.h"
@@ -530,7 +533,7 @@ static void test_load_env_file_1(void) {
         _cleanup_strv_free_ char **data = NULL;
         int r;
 
-        char name[] = "/tmp/test-load-env-file.XXXXXX";
+        _cleanup_(unlink_tempfilep) char name[] = "/tmp/test-load-env-file.XXXXXX";
         _cleanup_close_ int fd;
 
         fd = mkostemp_safe(name);
@@ -546,14 +549,13 @@ static void test_load_env_file_1(void) {
         assert_se(streq(data[4], "h=h"));
         assert_se(streq(data[5], "i=i"));
         assert_se(data[6] == NULL);
-        unlink(name);
 }
 
 static void test_load_env_file_2(void) {
         _cleanup_strv_free_ char **data = NULL;
         int r;
 
-        char name[] = "/tmp/test-load-env-file.XXXXXX";
+        _cleanup_(unlink_tempfilep) char name[] = "/tmp/test-load-env-file.XXXXXX";
         _cleanup_close_ int fd;
 
         fd = mkostemp_safe(name);
@@ -564,14 +566,13 @@ static void test_load_env_file_2(void) {
         assert_se(r == 0);
         assert_se(streq(data[0], "a=a"));
         assert_se(data[1] == NULL);
-        unlink(name);
 }
 
 static void test_load_env_file_3(void) {
         _cleanup_strv_free_ char **data = NULL;
         int r;
 
-        char name[] = "/tmp/test-load-env-file.XXXXXX";
+        _cleanup_(unlink_tempfilep) char name[] = "/tmp/test-load-env-file.XXXXXX";
         _cleanup_close_ int fd;
 
         fd = mkostemp_safe(name);
@@ -581,12 +582,11 @@ static void test_load_env_file_3(void) {
         r = load_env_file(NULL, name, NULL, &data);
         assert_se(r == 0);
         assert_se(data == NULL);
-        unlink(name);
 }
 
 static void test_load_env_file_4(void) {
         _cleanup_strv_free_ char **data = NULL;
-        char name[] = "/tmp/test-load-env-file.XXXXXX";
+        _cleanup_(unlink_tempfilep) char name[] = "/tmp/test-load-env-file.XXXXXX";
         _cleanup_close_ int fd;
         int r;
 
@@ -600,14 +600,13 @@ static void test_load_env_file_4(void) {
         assert_se(streq(data[1], "MODULE_0=coretemp"));
         assert_se(streq(data[2], "MODULE_1=f71882fg"));
         assert_se(data[3] == NULL);
-        unlink(name);
 }
 
 static void test_load_env_file_5(void) {
         _cleanup_strv_free_ char **data = NULL;
         int r;
 
-        char name[] = "/tmp/test-load-env-file.XXXXXX";
+        _cleanup_(unlink_tempfilep) char name[] = "/tmp/test-load-env-file.XXXXXX";
         _cleanup_close_ int fd;
 
         fd = mkostemp_safe(name);
@@ -619,7 +618,6 @@ static void test_load_env_file_5(void) {
         assert_se(streq(data[0], "a="));
         assert_se(streq(data[1], "b="));
         assert_se(data[2] == NULL);
-        unlink(name);
 }
 
 static void test_install_printf(void) {
@@ -747,22 +745,22 @@ static void test_config_parse_capability_set(void) {
 static void test_config_parse_rlimit(void) {
         struct rlimit * rl[_RLIMIT_MAX] = {};
 
-        assert_se(config_parse_limit(NULL, "fake", 1, "section", 1, "LimitNOFILE", RLIMIT_NOFILE, "55", rl, NULL) >= 0);
+        assert_se(config_parse_rlimit(NULL, "fake", 1, "section", 1, "LimitNOFILE", RLIMIT_NOFILE, "55", rl, NULL) >= 0);
         assert_se(rl[RLIMIT_NOFILE]);
         assert_se(rl[RLIMIT_NOFILE]->rlim_cur == 55);
         assert_se(rl[RLIMIT_NOFILE]->rlim_cur == rl[RLIMIT_NOFILE]->rlim_max);
 
-        assert_se(config_parse_limit(NULL, "fake", 1, "section", 1, "LimitNOFILE", RLIMIT_NOFILE, "55:66", rl, NULL) >= 0);
+        assert_se(config_parse_rlimit(NULL, "fake", 1, "section", 1, "LimitNOFILE", RLIMIT_NOFILE, "55:66", rl, NULL) >= 0);
         assert_se(rl[RLIMIT_NOFILE]);
         assert_se(rl[RLIMIT_NOFILE]->rlim_cur == 55);
         assert_se(rl[RLIMIT_NOFILE]->rlim_max == 66);
 
-        assert_se(config_parse_limit(NULL, "fake", 1, "section", 1, "LimitNOFILE", RLIMIT_NOFILE, "infinity", rl, NULL) >= 0);
+        assert_se(config_parse_rlimit(NULL, "fake", 1, "section", 1, "LimitNOFILE", RLIMIT_NOFILE, "infinity", rl, NULL) >= 0);
         assert_se(rl[RLIMIT_NOFILE]);
         assert_se(rl[RLIMIT_NOFILE]->rlim_cur == RLIM_INFINITY);
         assert_se(rl[RLIMIT_NOFILE]->rlim_cur == rl[RLIMIT_NOFILE]->rlim_max);
 
-        assert_se(config_parse_limit(NULL, "fake", 1, "section", 1, "LimitNOFILE", RLIMIT_NOFILE, "infinity:infinity", rl, NULL) >= 0);
+        assert_se(config_parse_rlimit(NULL, "fake", 1, "section", 1, "LimitNOFILE", RLIMIT_NOFILE, "infinity:infinity", rl, NULL) >= 0);
         assert_se(rl[RLIMIT_NOFILE]);
         assert_se(rl[RLIMIT_NOFILE]->rlim_cur == RLIM_INFINITY);
         assert_se(rl[RLIMIT_NOFILE]->rlim_cur == rl[RLIMIT_NOFILE]->rlim_max);
@@ -771,86 +769,86 @@ static void test_config_parse_rlimit(void) {
         rl[RLIMIT_NOFILE]->rlim_max = 20;
 
         /* Invalid values don't change rl */
-        assert_se(config_parse_limit(NULL, "fake", 1, "section", 1, "LimitNOFILE", RLIMIT_NOFILE, "10:20:30", rl, NULL) >= 0);
+        assert_se(config_parse_rlimit(NULL, "fake", 1, "section", 1, "LimitNOFILE", RLIMIT_NOFILE, "10:20:30", rl, NULL) >= 0);
         assert_se(rl[RLIMIT_NOFILE]);
         assert_se(rl[RLIMIT_NOFILE]->rlim_cur == 10);
         assert_se(rl[RLIMIT_NOFILE]->rlim_max == 20);
 
-        assert_se(config_parse_limit(NULL, "fake", 1, "section", 1, "LimitNOFILE", RLIMIT_NOFILE, "wat:wat", rl, NULL) >= 0);
+        assert_se(config_parse_rlimit(NULL, "fake", 1, "section", 1, "LimitNOFILE", RLIMIT_NOFILE, "wat:wat", rl, NULL) >= 0);
         assert_se(rl[RLIMIT_NOFILE]);
         assert_se(rl[RLIMIT_NOFILE]->rlim_cur == 10);
         assert_se(rl[RLIMIT_NOFILE]->rlim_max == 20);
 
-        assert_se(config_parse_limit(NULL, "fake", 1, "section", 1, "LimitNOFILE", RLIMIT_NOFILE, "66:wat", rl, NULL) >= 0);
+        assert_se(config_parse_rlimit(NULL, "fake", 1, "section", 1, "LimitNOFILE", RLIMIT_NOFILE, "66:wat", rl, NULL) >= 0);
         assert_se(rl[RLIMIT_NOFILE]);
         assert_se(rl[RLIMIT_NOFILE]->rlim_cur == 10);
         assert_se(rl[RLIMIT_NOFILE]->rlim_max == 20);
 
-        assert_se(config_parse_limit(NULL, "fake", 1, "section", 1, "LimitNOFILE", RLIMIT_NOFILE, "200:100", rl, NULL) >= 0);
+        assert_se(config_parse_rlimit(NULL, "fake", 1, "section", 1, "LimitNOFILE", RLIMIT_NOFILE, "200:100", rl, NULL) >= 0);
         assert_se(rl[RLIMIT_NOFILE]);
         assert_se(rl[RLIMIT_NOFILE]->rlim_cur == 10);
         assert_se(rl[RLIMIT_NOFILE]->rlim_max == 20);
 
         rl[RLIMIT_NOFILE] = mfree(rl[RLIMIT_NOFILE]);
 
-        assert_se(config_parse_limit(NULL, "fake", 1, "section", 1, "LimitCPU", RLIMIT_CPU, "56", rl, NULL) >= 0);
+        assert_se(config_parse_rlimit(NULL, "fake", 1, "section", 1, "LimitCPU", RLIMIT_CPU, "56", rl, NULL) >= 0);
         assert_se(rl[RLIMIT_CPU]);
         assert_se(rl[RLIMIT_CPU]->rlim_cur == 56);
         assert_se(rl[RLIMIT_CPU]->rlim_cur == rl[RLIMIT_CPU]->rlim_max);
 
-        assert_se(config_parse_limit(NULL, "fake", 1, "section", 1, "LimitCPU", RLIMIT_CPU, "57s", rl, NULL) >= 0);
+        assert_se(config_parse_rlimit(NULL, "fake", 1, "section", 1, "LimitCPU", RLIMIT_CPU, "57s", rl, NULL) >= 0);
         assert_se(rl[RLIMIT_CPU]);
         assert_se(rl[RLIMIT_CPU]->rlim_cur == 57);
         assert_se(rl[RLIMIT_CPU]->rlim_cur == rl[RLIMIT_CPU]->rlim_max);
 
-        assert_se(config_parse_limit(NULL, "fake", 1, "section", 1, "LimitCPU", RLIMIT_CPU, "40s:1m", rl, NULL) >= 0);
+        assert_se(config_parse_rlimit(NULL, "fake", 1, "section", 1, "LimitCPU", RLIMIT_CPU, "40s:1m", rl, NULL) >= 0);
         assert_se(rl[RLIMIT_CPU]);
         assert_se(rl[RLIMIT_CPU]->rlim_cur == 40);
         assert_se(rl[RLIMIT_CPU]->rlim_max == 60);
 
-        assert_se(config_parse_limit(NULL, "fake", 1, "section", 1, "LimitCPU", RLIMIT_CPU, "infinity", rl, NULL) >= 0);
+        assert_se(config_parse_rlimit(NULL, "fake", 1, "section", 1, "LimitCPU", RLIMIT_CPU, "infinity", rl, NULL) >= 0);
         assert_se(rl[RLIMIT_CPU]);
         assert_se(rl[RLIMIT_CPU]->rlim_cur == RLIM_INFINITY);
         assert_se(rl[RLIMIT_CPU]->rlim_cur == rl[RLIMIT_CPU]->rlim_max);
 
-        assert_se(config_parse_limit(NULL, "fake", 1, "section", 1, "LimitCPU", RLIMIT_CPU, "1234ms", rl, NULL) >= 0);
+        assert_se(config_parse_rlimit(NULL, "fake", 1, "section", 1, "LimitCPU", RLIMIT_CPU, "1234ms", rl, NULL) >= 0);
         assert_se(rl[RLIMIT_CPU]);
         assert_se(rl[RLIMIT_CPU]->rlim_cur == 2);
         assert_se(rl[RLIMIT_CPU]->rlim_cur == rl[RLIMIT_CPU]->rlim_max);
 
         rl[RLIMIT_CPU] = mfree(rl[RLIMIT_CPU]);
 
-        assert_se(config_parse_limit(NULL, "fake", 1, "section", 1, "LimitRTTIME", RLIMIT_RTTIME, "58", rl, NULL) >= 0);
+        assert_se(config_parse_rlimit(NULL, "fake", 1, "section", 1, "LimitRTTIME", RLIMIT_RTTIME, "58", rl, NULL) >= 0);
         assert_se(rl[RLIMIT_RTTIME]);
         assert_se(rl[RLIMIT_RTTIME]->rlim_cur == 58);
         assert_se(rl[RLIMIT_RTTIME]->rlim_cur == rl[RLIMIT_RTTIME]->rlim_max);
 
-        assert_se(config_parse_limit(NULL, "fake", 1, "section", 1, "LimitRTTIME", RLIMIT_RTTIME, "58:60", rl, NULL) >= 0);
+        assert_se(config_parse_rlimit(NULL, "fake", 1, "section", 1, "LimitRTTIME", RLIMIT_RTTIME, "58:60", rl, NULL) >= 0);
         assert_se(rl[RLIMIT_RTTIME]);
         assert_se(rl[RLIMIT_RTTIME]->rlim_cur == 58);
         assert_se(rl[RLIMIT_RTTIME]->rlim_max == 60);
 
-        assert_se(config_parse_limit(NULL, "fake", 1, "section", 1, "LimitRTTIME", RLIMIT_RTTIME, "59s", rl, NULL) >= 0);
+        assert_se(config_parse_rlimit(NULL, "fake", 1, "section", 1, "LimitRTTIME", RLIMIT_RTTIME, "59s", rl, NULL) >= 0);
         assert_se(rl[RLIMIT_RTTIME]);
         assert_se(rl[RLIMIT_RTTIME]->rlim_cur == 59 * USEC_PER_SEC);
         assert_se(rl[RLIMIT_RTTIME]->rlim_cur == rl[RLIMIT_RTTIME]->rlim_max);
 
-        assert_se(config_parse_limit(NULL, "fake", 1, "section", 1, "LimitRTTIME", RLIMIT_RTTIME, "59s:123s", rl, NULL) >= 0);
+        assert_se(config_parse_rlimit(NULL, "fake", 1, "section", 1, "LimitRTTIME", RLIMIT_RTTIME, "59s:123s", rl, NULL) >= 0);
         assert_se(rl[RLIMIT_RTTIME]);
         assert_se(rl[RLIMIT_RTTIME]->rlim_cur == 59 * USEC_PER_SEC);
         assert_se(rl[RLIMIT_RTTIME]->rlim_max == 123 * USEC_PER_SEC);
 
-        assert_se(config_parse_limit(NULL, "fake", 1, "section", 1, "LimitRTTIME", RLIMIT_RTTIME, "infinity", rl, NULL) >= 0);
+        assert_se(config_parse_rlimit(NULL, "fake", 1, "section", 1, "LimitRTTIME", RLIMIT_RTTIME, "infinity", rl, NULL) >= 0);
         assert_se(rl[RLIMIT_RTTIME]);
         assert_se(rl[RLIMIT_RTTIME]->rlim_cur == RLIM_INFINITY);
         assert_se(rl[RLIMIT_RTTIME]->rlim_cur == rl[RLIMIT_RTTIME]->rlim_max);
 
-        assert_se(config_parse_limit(NULL, "fake", 1, "section", 1, "LimitRTTIME", RLIMIT_RTTIME, "infinity:infinity", rl, NULL) >= 0);
+        assert_se(config_parse_rlimit(NULL, "fake", 1, "section", 1, "LimitRTTIME", RLIMIT_RTTIME, "infinity:infinity", rl, NULL) >= 0);
         assert_se(rl[RLIMIT_RTTIME]);
         assert_se(rl[RLIMIT_RTTIME]->rlim_cur == RLIM_INFINITY);
         assert_se(rl[RLIMIT_RTTIME]->rlim_cur == rl[RLIMIT_RTTIME]->rlim_max);
 
-        assert_se(config_parse_limit(NULL, "fake", 1, "section", 1, "LimitRTTIME", RLIMIT_RTTIME, "2345ms", rl, NULL) >= 0);
+        assert_se(config_parse_rlimit(NULL, "fake", 1, "section", 1, "LimitRTTIME", RLIMIT_RTTIME, "2345ms", rl, NULL) >= 0);
         assert_se(rl[RLIMIT_RTTIME]);
         assert_se(rl[RLIMIT_RTTIME]->rlim_cur == 2345 * USEC_PER_MSEC);
         assert_se(rl[RLIMIT_RTTIME]->rlim_cur == rl[RLIMIT_RTTIME]->rlim_max);
index bb44bc25458c9b8cd0ceac428bdd94989d66d356..692c3f41cff066d667615735fa8c8f1496864b37 100644 (file)
@@ -13,6 +13,7 @@
 #include <string.h>
 
 #include "alloc-util.h"
+#include "all-units.h"
 #include "glob-util.h"
 #include "hostname-util.h"
 #include "macro.h"
index c280374582c42b224aab0fbbb40f361667b19fe2..cb43b35bc5d986e254824232079b4c3ee8e319d4 100644 (file)
@@ -3,6 +3,7 @@
 #include "log.h"
 #include "manager.h"
 #include "rm-rf.h"
+#include "service.h"
 #include "test-helper.h"
 #include "tests.h"
 
index d488572ae3b527d5d59c73d8fe3d60d933dbddcf..b6303ba1dd20739268a0c166fb2754e9f47c5e01 100644 (file)
@@ -41,8 +41,7 @@
 
         <action id="org.freedesktop.timedate1.set-local-rtc">
                 <description gettext-domain="systemd">Set RTC to local timezone or UTC</description>
-                <message gettext-domain="systemd">Authentication is required to control whether
-                the RTC stores the local or UTC time.</message>
+                <message gettext-domain="systemd">Authentication is required to control whether the RTC stores the local or UTC time.</message>
                 <defaults>
                         <allow_any>auth_admin_keep</allow_any>
                         <allow_inactive>auth_admin_keep</allow_inactive>
@@ -52,8 +51,7 @@
 
         <action id="org.freedesktop.timedate1.set-ntp">
                 <description gettext-domain="systemd">Turn network time synchronization on or off</description>
-                <message gettext-domain="systemd">Authentication is required to control whether
-                network time synchronization shall be enabled.</message>
+                <message gettext-domain="systemd">Authentication is required to control whether network time synchronization shall be enabled.</message>
                 <defaults>
                         <allow_any>auth_admin_keep</allow_any>
                         <allow_inactive>auth_admin_keep</allow_inactive>
index 6928bb9a971ff5b8e6aada5ec1a117e223a37a0a..e066320cffe4ade13fa2d8014fa6fe9bab893580 100644 (file)
@@ -427,6 +427,9 @@ static int unit_enable_or_disable(UnitStatusInfo *u, sd_bus *bus, sd_bus_error *
         return 0;
 }
 
+static BUS_DEFINE_PROPERTY_GET_GLOBAL(property_get_time, "t", now(CLOCK_REALTIME));
+static BUS_DEFINE_PROPERTY_GET_GLOBAL(property_get_ntp_sync, "b", ntp_synced());
+
 static int property_get_rtc_time(
                 sd_bus *bus,
                 const char *path,
@@ -456,30 +459,6 @@ static int property_get_rtc_time(
         return sd_bus_message_append(reply, "t", t);
 }
 
-static int property_get_time(
-                sd_bus *bus,
-                const char *path,
-                const char *interface,
-                const char *property,
-                sd_bus_message *reply,
-                void *userdata,
-                sd_bus_error *error) {
-
-        return sd_bus_message_append(reply, "t", now(CLOCK_REALTIME));
-}
-
-static int property_get_ntp_sync(
-                sd_bus *bus,
-                const char *path,
-                const char *interface,
-                const char *property,
-                sd_bus_message *reply,
-                void *userdata,
-                sd_bus_error *error) {
-
-        return sd_bus_message_append(reply, "b", ntp_synced());
-}
-
 static int property_get_can_ntp(
                 sd_bus *bus,
                 const char *path,
@@ -545,10 +524,7 @@ static int method_set_timezone(sd_bus_message *m, void *userdata, sd_bus_error *
         if (!timezone_is_valid(z, LOG_DEBUG))
                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid time zone '%s'", z);
 
-        r = free_and_strdup(&c->zone, z);
-        if (r < 0)
-                return r;
-        if (r == 0)
+        if (streq_ptr(z, c->zone))
                 return sd_bus_reply_method_return(m, NULL);
 
         r = bus_verify_polkit_async(
@@ -565,6 +541,10 @@ static int method_set_timezone(sd_bus_message *m, void *userdata, sd_bus_error *
         if (r == 0)
                 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
 
+        r = free_and_strdup(&c->zone, z);
+        if (r < 0)
+                return r;
+
         /* 1. Write new configuration file */
         r = context_write_data_timezone(c);
         if (r < 0) {
index 1932043fb95c9ed439ac5def6a8d0b229bc44e51..6243debfebe8de9d398aed50da4ce9cf43641e24 100644 (file)
@@ -56,7 +56,7 @@ static int property_get_current_server_name(
         assert(bus);
         assert(reply);
 
-        return sd_bus_message_append(reply, "s", *s ? (*s)->string : "");
+        return sd_bus_message_append(reply, "s", *s ? (*s)->string : NULL);
 }
 
 static int property_get_current_server_address(
index 46098c215c3546a056284cf5e61f2602713e8f54..672405897b6124f1968171ce8b49d498d2837631 100644 (file)
@@ -2115,6 +2115,43 @@ static int specifier_expansion_from_arg(Item *i) {
         return 0;
 }
 
+static int patch_var_run(const char *fname, unsigned line, char **path) {
+        const char *k;
+        char *n;
+
+        assert(path);
+        assert(*path);
+
+        /* Optionally rewrites lines referencing /var/run/, to use /run/ instead. Why bother? tmpfiles merges lines in
+         * some cases and detects conflicts in others. If files/directories are specified through two equivalent lines
+         * this is problematic as neither case will be detected. Ideally we'd detect these cases by resolving symlinks
+         * early, but that's precisely not what we can do here as this code very likely is running very early on, at a
+         * time where the paths in question are not available yet, or even more importantly, our own tmpfiles rules
+         * might create the paths that are intermediary to the listed paths. We can't really cover the generic case,
+         * but the least we can do is cover the specific case of /var/run vs. /run, as /var/run is a legacy name for
+         * /run only, and we explicitly document that and require that on systemd systems the former is a symlink to
+         * the latter. Moreover files below this path are by far the primary usecase for tmpfiles.d/. */
+
+        k = path_startswith(*path, "/var/run/");
+        if (isempty(k)) /* Don't complain about other paths than /var/run, and not about /var/run itself either. */
+                return 0;
+
+        n = strjoin("/run/", k);
+        if (!n)
+                return log_oom();
+
+        /* Also log about this briefly. We do so at LOG_NOTICE level, as we fixed up the situation automatically, hence
+         * there's no immediate need for action by the user. However, in the interest of making things less confusing
+         * to the user, let's still inform the user that these snippets should really be updated. */
+
+        log_notice("[%s:%u] Line references path below legacy directory /var/run/, updating %s → %s; please update the tmpfiles.d/ drop-in file accordingly.", fname, line, *path, n);
+
+        free(*path);
+        *path = n;
+
+        return 0;
+}
+
 static int parse_line(const char *fname, unsigned line, const char *buffer, bool *invalid_config) {
 
         _cleanup_free_ char *action = NULL, *mode = NULL, *user = NULL, *group = NULL, *age = NULL, *path = NULL;
@@ -2193,6 +2230,10 @@ static int parse_line(const char *fname, unsigned line, const char *buffer, bool
                 return log_error_errno(r, "[%s:%u] Failed to replace specifiers: %s", fname, line, path);
         }
 
+        r = patch_var_run(fname, line, &i.path);
+        if (r < 0)
+                return r;
+
         switch (i.type) {
 
         case CREATE_DIRECTORY:
index 76e3829ab21232a9e62ca77f7cd38edf78b0dc88..d39c9cbbcf4aab47d379b674bcd14f523176a606 100644 (file)
@@ -71,3 +71,7 @@ a+ /var/log/journal/%m/system.journal - - - - group:wheel:r--
 
 d /var/lib/systemd 0755 root root -
 d /var/lib/systemd/coredump 0755 root root 3d
+
+d /var/lib/private 0700 root root -
+d /var/log/private 0700 root root -
+d /var/cache/private 0700 root root -