]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
Merge pull request #8817 from yuwata/cleanup-nsflags
authorLennart Poettering <lennart@poettering.net>
Thu, 24 May 2018 14:49:13 +0000 (16:49 +0200)
committerGitHub <noreply@github.com>
Thu, 24 May 2018 14:49:13 +0000 (16:49 +0200)
core: allow to specify RestrictNamespaces= multiple times

317 files changed:
.github/ISSUE_TEMPLATE.md [deleted file]
.github/ISSUE_TEMPLATE/Bug_report.md [new file with mode: 0644]
.github/ISSUE_TEMPLATE/Feature_request.md [new file with mode: 0644]
.travis.yml
NEWS
README
TODO
doc/CGROUP_DELEGATION.md
doc/UIDS-GIDS.md
man/coredump.conf.xml
man/journal-remote.conf.xml
man/journal-upload.conf.xml
man/journalctl.xml
man/resolvectl.xml
man/rules/meson.build
man/standard-options.xml
man/systemctl.xml
man/systemd-analyze.xml
man/systemd-ask-password.xml
man/systemd-binfmt.service.xml
man/systemd-cgtop.xml
man/systemd-coredump.xml
man/systemd-detect-virt.xml
man/systemd-escape.xml
man/systemd-inhibit.xml
man/systemd-journal-gatewayd.service.xml
man/systemd-journal-remote.service.xml [moved from man/systemd-journal-remote.xml with 87% similarity]
man/systemd-journal-upload.service.xml [moved from man/systemd-journal-upload.xml with 87% similarity]
man/systemd-networkd-wait-online.service.xml
man/systemd-nspawn.xml
man/systemd-sysctl.service.xml
man/systemd-sysusers.xml
man/systemd-tmpfiles.xml
man/systemd.exec.xml
man/systemd.link.xml
man/systemd.network.xml
man/systemd.nspawn.xml
man/systemd.service.xml
man/systemd.special.xml
man/systemd.unit.xml
man/udevadm.xml
meson.build
meson_options.txt
po/uk.po
rules/60-persistent-storage.rules
shell-completion/bash/busctl
shell-completion/bash/systemd-analyze
shell-completion/bash/timedatectl
src/analyze/analyze-verify.c
src/analyze/analyze.c
src/basic/MurmurHash2.c
src/basic/MurmurHash2.h
src/basic/calendarspec.c
src/basic/conf-files.c
src/basic/conf-files.h
src/basic/def.h
src/basic/env-util.c
src/basic/ether-addr-util.c
src/basic/ether-addr-util.h
src/basic/fd-util.c
src/basic/format-table.c
src/basic/fs-util.c
src/basic/fs-util.h
src/basic/hashmap.c
src/basic/hexdecoct.c
src/basic/log.c
src/basic/log.h
src/basic/mempool.c
src/basic/mempool.h
src/basic/meson.build
src/basic/missing.h
src/basic/missing_syscall.h
src/basic/parse-util.c
src/basic/parse-util.h
src/basic/path-util.c
src/basic/path-util.h
src/basic/process-util.c
src/basic/process-util.h
src/basic/ratelimit.c
src/basic/ratelimit.h
src/basic/rlimit-util.c
src/basic/rlimit-util.h
src/basic/rm-rf.c
src/basic/strbuf.h
src/basic/string-table.h
src/basic/string-util.h
src/basic/strv.c
src/basic/strxcpyx.h
src/basic/terminal-util.c
src/basic/terminal-util.h
src/basic/time-util.c
src/basic/time-util.h
src/basic/util.c
src/binfmt/binfmt.c
src/busctl/busctl.c
src/cgls/cgls.c
src/cgtop/cgtop.c
src/core/all-units.h [new file with mode: 0644]
src/core/automount.h
src/core/cgroup.h
src/core/dbus-automount.h
src/core/dbus-cgroup.h
src/core/dbus-execute.c
src/core/dbus-manager.c
src/core/dbus-mount.c
src/core/dbus-path.c
src/core/dbus-scope.h
src/core/dbus-service.c
src/core/dbus-socket.c
src/core/dbus-swap.c
src/core/dbus-timer.c
src/core/dbus-unit.c
src/core/dbus-util.c
src/core/dbus-util.h
src/core/dbus.c
src/core/device.c
src/core/device.h
src/core/dynamic-user.c
src/core/execute.c
src/core/ip-address-access.h
src/core/job.c
src/core/job.h
src/core/load-fragment-gperf.gperf.m4
src/core/load-fragment.c
src/core/load-fragment.h
src/core/locale-setup.c
src/core/macros.systemd.in
src/core/main.c
src/core/manager.c
src/core/manager.h
src/core/meson.build
src/core/mount-setup.c
src/core/mount.c
src/core/mount.h
src/core/namespace.c
src/core/org.freedesktop.systemd1.conf
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.c
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/coredump/coredumpctl.c
src/detect-virt/detect-virt.c
src/firstboot/firstboot.c
src/hostname/hostnamed.c
src/import/export-raw.c
src/import/export-tar.c
src/import/import-raw.c
src/import/import-tar.c
src/journal/catalog.c
src/journal/journalctl.c
src/journal/journald-server.h
src/journal/lookup3.c
src/journal/sd-journal.c
src/journal/test-catalog.c
src/journal/test-compress.c
src/libsystemd-network/dhcp-option.c
src/libsystemd-network/network-internal.c
src/libsystemd-network/network-internal.h
src/libsystemd-network/sd-dhcp-client.c
src/libsystemd-network/sd-dhcp-lease.c
src/libsystemd-network/sd-dhcp-server.c
src/libsystemd-network/sd-dhcp6-lease.c
src/libsystemd-network/test-dhcp-client.c
src/libsystemd/meson.build
src/libsystemd/sd-bus/bus-internal.h
src/libsystemd/sd-bus/bus-message.c
src/libsystemd/sd-bus/bus-socket.c
src/libsystemd/sd-bus/sd-bus.c
src/libsystemd/sd-bus/test-bus-server.c
src/libsystemd/sd-netlink/local-addresses.h
src/libsystemd/sd-resolve/sd-resolve.c
src/libsystemd/sd-resolve/test-resolve.c
src/libudev/libudev.h
src/locale/keymap-util.c
src/locale/localectl.c
src/login/inhibit.c
src/login/loginctl.c
src/login/logind-action.h
src/login/logind-dbus.c
src/login/logind-inhibit.h
src/login/logind-seat-dbus.c
src/login/logind-session-dbus.c
src/login/logind-user-dbus.c
src/login/logind-user.c
src/login/logind-user.h
src/login/logind.c
src/login/logind.h
src/login/meson.build
src/machine/machine-dbus.c
src/machine/machinectl.c
src/machine/machined-dbus.c
src/network/netdev/ipvlan.h
src/network/networkd-address-label.h
src/network/networkd-address.h
src/network/networkd-brvlan.h
src/network/networkd-conf.h
src/network/networkd-dhcp4.c
src/network/networkd-dhcp6.c
src/network/networkd-fdb.h
src/network/networkd-ipv6-proxy-ndp.h
src/network/networkd-manager.c
src/network/networkd-network-bus.c
src/network/networkd-network-gperf.gperf
src/network/networkd-network.c
src/network/networkd-network.h
src/network/networkd-radv.h
src/network/networkd-route.c
src/network/networkd-route.h
src/network/networkd-routing-policy-rule.h
src/network/networkd-util.h
src/network/test-networkd-conf.c
src/nspawn/nspawn-cgroup.c
src/nspawn/nspawn-cgroup.h
src/nspawn/nspawn-gperf.gperf
src/nspawn/nspawn-mount.c
src/nspawn/nspawn-mount.h
src/nspawn/nspawn-register.c
src/nspawn/nspawn-settings.c
src/nspawn/nspawn-settings.h
src/nspawn/nspawn.c
src/resolve/resolvectl.c
src/resolve/resolved-bus.c
src/resolve/resolved-conf.h
src/resolve/resolved-dns-dnssec.h
src/resolve/resolved-dns-query.h
src/resolve/resolved-dns-rr.h
src/resolve/resolved-dns-scope.c
src/resolve/resolved-dns-trust-anchor.c
src/resolve/resolved-link-bus.c
src/resolve/resolved-mdns.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/shared/gpt.h
src/shared/initreq.h
src/shared/install.c
src/shared/meson.build
src/shared/path-lookup.c
src/shared/resolve-util.h
src/shared/sleep-config.c
src/shared/vlan-util.h
src/shared/volatile-util.c
src/shared/volatile-util.h
src/sysctl/sysctl.c
src/systemctl/systemctl.c
src/systemd/sd-dhcp-client.h
src/systemd/sd-resolve.h
src/sysusers/sysusers.c
src/test/test-conf-parser.c
src/test/test-copy.c
src/test/test-dlopen.c
src/test/test-execute.c
src/test/test-fileio.c
src/test/test-hashmap.c
src/test/test-hexdecoct.c
src/test/test-nss.c
src/test/test-path.c
src/test/test-ratelimit.c
src/test/test-rlimit-util.c
src/test/test-sched-prio.c
src/test/test-sizeof.c
src/test/test-sleep.c
src/test/test-strbuf.c
src/test/test-terminal-util.c
src/test/test-time-util.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/timesync/timesyncd-conf.h
src/timesync/timesyncd-manager.c
src/tmpfiles/tmpfiles.c
src/udev/meson.build
src/udev/mtd_probe/mtd_probe.c
src/udev/mtd_probe/mtd_probe.h
src/udev/mtd_probe/probe_smartmedia.c
src/udev/net/ethtool-util.c
src/udev/net/ethtool-util.h
src/udev/net/link-config-gperf.gperf
src/udev/net/link-config.c
src/udev/net/link-config.h
src/udev/udevadm-hwdb.c
sysusers.d/meson.build
sysusers.d/systemd.conf.m4
test/networkd-test.py
test/test-execute/exec-dynamicuser-statedir-migrate-step2.service
test/test-execute/exec-environmentfile.service
test/test-execute/exec-passenvironment-absent.service
test/test-execute/exec-passenvironment-empty.service
test/test-execute/exec-passenvironment-repeated.service
test/test-execute/exec-passenvironment.service
tmpfiles.d/meson.build
tmpfiles.d/systemd.conf.m4
tools/find-double-newline.sh
tools/find-tabs.sh [new file with mode: 0755]
tools/meson-apply-m4.sh [new file with mode: 0755]
tools/oss-fuzz.sh
travis-ci/requirements.txt
units/meson.build
units/systemd-networkd.service.in
units/systemd-resolved.service.in
units/systemd-timesyncd.service.in

diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md
deleted file mode 100644 (file)
index 687270e..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-### Submission type
-
-<!-- Delete the inappropriate option below: -->
-
- - Bug report
- - Request for enhancement (RFE)
-
-<!-- **NOTE:** Do not submit anything other than bug reports or RFEs via the issue tracker! -->
-
-### systemd version the issue has been seen with
-
-> …
-
-<!-- **NOTE:** Do not submit bug reports about anything but the two most recently released systemd versions upstream! -->
-<!-- For older version please use distribution trackers (see https://github.com/systemd/systemd/blob/master/.github/CONTRIBUTING.md#filing-issues). -->
-
-### Used distribution
-
-> …
-
-### In case of bug report: Expected behaviour you didn't see
-
-> …
-
-### In case of bug report: Unexpected behaviour you saw
-
-> …
-
-### In case of bug report: Steps to reproduce the problem
-
-> …
diff --git a/.github/ISSUE_TEMPLATE/Bug_report.md b/.github/ISSUE_TEMPLATE/Bug_report.md
new file mode 100644 (file)
index 0000000..cea1c65
--- /dev/null
@@ -0,0 +1,22 @@
+---
+name: Bug report
+about: A report of an error in a recent systemd version
+
+---
+
+**systemd version the issue has been seen with**
+> ...
+
+<!-- **NOTE:** Do not submit bug reports about anything but the two most recently released systemd versions upstream! -->
+<!-- For older version please use distribution trackers (see https://github.com/systemd/systemd/blob/master/.github/CONTRIBUTING.md#filing-issues). -->
+
+**Used distribution**
+ > …
+
+**Expected behaviour you didn't see**
+ > …
+
+**Unexpected behaviour you saw**
+ > …
+
+**Steps to reproduce the problem**
diff --git a/.github/ISSUE_TEMPLATE/Feature_request.md b/.github/ISSUE_TEMPLATE/Feature_request.md
new file mode 100644 (file)
index 0000000..c56aae8
--- /dev/null
@@ -0,0 +1,14 @@
+---
+name: Feature request
+about: Suggest an improvement
+
+---
+
+**Is your feature request related to a problem? Please describe.**
+A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
+
+**Describe the solution you'd like**
+A clear and concise description of what you want to happen.
+
+**Describe alternatives you've considered**
+A clear and concise description of any alternative solutions or features you've considered.
index fc135868715fd3f954d39227bcf7df95d8659e17..c7c01017480b5bdefa17607c4cebf9aa6cff61f1 100644 (file)
@@ -2,6 +2,8 @@ sudo: required
 
 services:
     - docker
+    
+cache: ccache
 
 jobs:
     include:
@@ -35,7 +37,7 @@ jobs:
               - MACHINE_ID=$(cat /var/lib/dbus/machine-id)
           before_script: *update
           script:
-              - docker run -dit --name travis_build ${DOCKER_REPOSITORY}:${TRAVIS_COMMIT} bash
+              - docker run -v $HOME/.ccache:$HOME/.ccache -dit --name travis_build ${DOCKER_REPOSITORY}:${TRAVIS_COMMIT} bash
               - docker exec -u 0 -ti travis_build bash -c "echo ${MACHINE_ID} > /etc/machine-id"
               - docker exec -ti travis_build meson build
               - docker exec -ti travis_build ninja -C build
@@ -49,7 +51,7 @@ jobs:
           compiler: gcc
           before_script: *update
           script:
-              - docker run --privileged --net=host -dit --name travis_test ${DOCKER_REPOSITORY}:${TRAVIS_COMMIT} bash
+              - docker run -v $HOME/.ccache:$HOME/.ccache --privileged --net=host -dit --name travis_test ${DOCKER_REPOSITORY}:${TRAVIS_COMMIT} bash
               - docker exec -ti travis_test ninja -C build test
               - docker commit -m "systemd test state" -a "${AUTHOR_NAME}" travis_test ${DOCKER_REPOSITORY}:${TRAVIS_COMMIT}
               - docker login -u="${DOCKER_USERNAME}" -p="${DOCKER_PASSWORD}"
diff --git a/NEWS b/NEWS
index b05f601c38e92e4dd127e6a016cc9aaa85c1e53d..614a53cea21827b60c5be87a887bcb9f8968a675 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -9,6 +9,14 @@ CHANGES WITH 239 in spe:
           and udev may generate names based on PCI slot number in some cases
           where it previously did not.
 
+        * AF_INET and AF_INET6 are dropped from RestrictAddressFamilies= in
+          systemd-logind.service. Since v235, IPAddressDeny=any has been set to
+          the unit. So, it is expected that the default behavior of systemd-logind
+          is not changed. However, if distribution packagers or administrators
+          disabled or modified IPAddressDeny= setting by a drop-in config file,
+          then it may be necessary to update the file to re-enable AF_INET and
+          AF_INET6 to support network user name services, e.g. NIS.
+
 CHANGES WITH 238:
 
         * The MemoryAccounting= unit property now defaults to on. After
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
 
diff --git a/TODO b/TODO
index c8f75963905c35d0d325681513015fcc8a7b8b4c..bdb8a18de9358218e2aefd770eb1d7ad248eb00f 100644 (file)
--- a/TODO
+++ b/TODO
@@ -24,6 +24,10 @@ Janitorial Clean-ups:
 
 Features:
 
+* add O_TMPFILE support to copy_file_atomic()
+
+* nspawn: greater control over selinux label?
+
 * the error paths in usbffs_dispatch_ep() leak memory
 
 * cgroups: figure out if we can somehow communicate in a cleaner way whether a
@@ -52,9 +56,6 @@ Features:
 
 * add --vacuum-xyz options to coredumpctl, matching those journalctl already has.
 
-* list the exit codes from the BSD/glibc <sysexits.h> in our own
-  exit-codes.[ch] tables.
-
 * SuccessExitStatus= and friends should probably also accept symbolic exit
   codes names, i.e. error codes from the list maintained in exit-codes.[ch]
 
@@ -328,8 +329,6 @@ Features:
 * rework fopen_temporary() to make use of open_tmpfile_linkable() (problem: the
   kernel doesn't support linkat() that replaces existing files, currently)
 
-* check if DeviceAllow= should split first, resolve specifiers later
-
 * transient units: don't bother with actually setting unit properties, we
   reload the unit file anyway
 
@@ -560,7 +559,7 @@ Features:
   - document chaining of signal handler for SIGCHLD and child handlers
   - define more intervals where we will shift wakeup intervals around in, 1h, 6h, 24h, ...
   - generate a failure of a default event loop is executed out-of-thread
-  - maybe add support for inotify events
+  - maybe add support for inotify events (which we can do safely now, with O_PATH)
 
 * investigate endianness issues of UUID vs. GUID
 
index 412f0a5fa0e30a3ae1d43ccb178c27441ecce8d7..212283fd73d0b0e52432a76d011875c62235126d 100644 (file)
@@ -424,15 +424,16 @@ unified you (of course, I guess) need to provide only `/sys/fs/cgroup/` itself.
    cgroup tree of systemd itself is out of limits for you. It's fine to *read*
    from any attribute you like however. That's totally OK and welcome.
 
-4. 🚫 When not using `CLONE_NEWCGROUP` when delegating a sub-tree to a container
-   payload running systemd, then don't get the idea that you can bind mount
-   only a sub-tree of the host's cgroup tree into the container. Part of the
-   cgroup API is that `/proc/$PID/cgroup` reports the cgroup path of every
+4. 🚫 When not using `CLONE_NEWCGROUP` when delegating a sub-tree to a
+   container payload running systemd, then don't get the idea that you can bind
+   mount only a sub-tree of the host's cgroup tree into the container. Part of
+   the cgroup API is that `/proc/$PID/cgroup` reports the cgroup path of every
    process, and hence any path below `/sys/fs/cgroup/` needs to match what
    `/proc/$PID/cgroup` of the payload processes reports. What you can do safely
-   however, is mount the upper parts of the cgroup tree read-only or even
-   replace it with an intermediary `tmpfs`, as long as the path to the
-   delegated sub-tree remains accessible as-is.
+   however, is mount the upper parts of the cgroup tree read-only (or even
+   replace the middle bits with an intermediary `tmpfs` — but be careful not to
+   break the `statfs()` detection logic discussed above), as long as the path
+   to the delegated sub-tree remains accessible as-is.
 
 5. ⚡ Currently, the algorithm for mapping between slice/scope/service unit
    naming and their cgroup paths is not considered public API of systemd, and
index e19cc88162378b40c935639daa69c9f64923b8cc..c380bbe140a92da00615e5a7cdd2913588c047ff 100644 (file)
@@ -241,3 +241,38 @@ really unused. It just means that these ranges have no well-established
 pre-defined purposes between Linux, generic low-level distributions and
 `systemd`. There might very well be other packages that allocate from these
 ranges.
+
+## Notes on resolvability of user and group names
+
+User names, UIDs, group names and GIDs don't have to be resolvable using NSS
+(i.e. getpwuid() and getpwnam() and friends) all the time. However, systemd
+makes the following requirements:
+
+System users generally have to be resolvable during early boot already. This
+means they should not be provided by any networked service (as those usually
+become available during late boot only), except if a local cache is kept that
+makes them available during early boot too (i.e. before networking is
+up). Specifically, system users need to be resolvable at least before
+`systemd-udevd.service` and `systemd-tmpfiles.service` are started, as both
+need to resolve system users — but note that there might be more services
+requiring full resolvability of system users than just these two.
+
+Regular users do not need to be resolvable during early boot, it is sufficient
+if they become resolvable during late boot. Specifically, regular users need to
+be resolvable at the point in time the `nss-user-lookup.target` unit is
+reached. This target unit is generally used as synchronization point between
+providers of the user database and consumers of it. Services that require that
+the user database is fully available (for example, the login service
+`systemd-logind.service`) are ordered *after* it, while services that provide
+parts of the user database (for example an LDAP user database client) are
+ordered *before* it. Note that `nss-user-lookup.target` is a *passive* unit: in
+order to minimize synchronization points on systems that don't need it the unit
+is pulled into the initial transaction only if there's at least one service
+that really needs it, and that means only if there's a service providing the
+local user database somehow through IPC or suchlike. Or in other words: if you
+hack on some networked user database project, then make sure you order your
+service `Before=nss-user-lookup.target` and that you pull it in with
+`Wants=nss-user-lookup.target`. However, if you hack on some project that needs
+the user database to be up in full, then order your service
+`After=nss-user-lookup.target`, but do *not* pull it in via a `Wants=`
+dependency.
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 db5e4efd5b25cef0846fb8825c354bf2f4d02b79..42ecabc807480fcbb47b8f4b37a885b216d7a010 100644 (file)
@@ -86,7 +86,7 @@
       <varlistentry>
         <term><varname>ServerCertificateFile=</varname></term>
 
-        <listitem><para>SSL CA certificate in PEM format.</para></listitem>
+        <listitem><para>SSL certificate in PEM format.</para></listitem>
       </varlistentry>
 
       <varlistentry>
   <refsect1>
       <title>See Also</title>
       <para>
-        <citerefentry><refentrytitle>systemd-journal-remote</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+        <citerefentry><refentrytitle>systemd-journal-remote.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
         <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
         <citerefentry><refentrytitle>systemd-journald.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>
       </para>
index 8e241370db001bf97545de94e3901ea239f79ba5..cd3335452afb28e889c1129840c3882baa68e3d5 100644 (file)
@@ -68,7 +68,8 @@
         <listitem><para>The URL to upload the journal entries to. See the description
         of <varname>--url=</varname> option in
         <citerefentry><refentrytitle>systemd-journal-upload</refentrytitle><manvolnum>8</manvolnum></citerefentry>
-        for the description of possible values.</para></listitem>
+        for the description of possible values. There is no default value, so either this
+        option or the command-line option must be always present to make an upload.</para></listitem>
       </varlistentry>
 
       <varlistentry>
@@ -96,7 +97,7 @@
   <refsect1>
       <title>See Also</title>
       <para>
-        <citerefentry><refentrytitle>systemd-journal-upload</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+        <citerefentry><refentrytitle>systemd-journal-upload.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
         <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
         <citerefentry><refentrytitle>systemd-journald.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>
       </para>
index 1bec2b79fb5b4c815869915408c0db7f3d3f8128..12d6a80c573375b8f6afec685b12a89437538912 100644 (file)
@@ -976,8 +976,8 @@ journalctl _SYSTEMD_CGROUP=/user.slice/user-42.slice/session-c1.scope</programli
       <citerefentry><refentrytitle>systemd.journal-fields</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
       <citerefentry><refentrytitle>journald.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
       <citerefentry><refentrytitle>systemd.time</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
-      <citerefentry><refentrytitle>systemd-journal-remote</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
-      <citerefentry><refentrytitle>systemd-journal-upload</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+      <citerefentry><refentrytitle>systemd-journal-remote.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+      <citerefentry><refentrytitle>systemd-journal-upload.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>
     </para>
   </refsect1>
 </refentry>
index 96b3e8dad31e5e9ae7847f5dd156fc53c28b9166..7f981ac327f6022a703b63e3bbb4442d47c23983 100644 (file)
     <example>
       <title>Retrieve the addresses of the <literal>www.0pointer.net</literal> domain</title>
 
-      <programlisting>$ resolvectl www.0pointer.net
+      <programlisting>$ resolvectl query www.0pointer.net
 www.0pointer.net: 2a01:238:43ed:c300:10c3:bcf3:3266:da74
                   85.214.157.71
 
@@ -382,7 +382,7 @@ www.0pointer.net: 2a01:238:43ed:c300:10c3:bcf3:3266:da74
     <example>
       <title>Retrieve the domain of the <literal>85.214.157.71</literal> IP address</title>
 
-      <programlisting>$ resolvectl 85.214.157.71
+      <programlisting>$ resolvectl query 85.214.157.71
 85.214.157.71: gardel.0pointer.net
 
 -- Information acquired via protocol DNS in 1.2997s.
@@ -393,7 +393,7 @@ www.0pointer.net: 2a01:238:43ed:c300:10c3:bcf3:3266:da74
     <example>
       <title>Retrieve the MX record of the <literal>yahoo.com</literal> domain</title>
 
-      <programlisting>$ resolvectl -t MX yahoo.com --legend=no
+      <programlisting>$ resolvectl --legend=no -t MX query yahoo.com
 yahoo.com. IN MX    1 mta7.am0.yahoodns.net
 yahoo.com. IN MX    1 mta6.am0.yahoodns.net
 yahoo.com. IN MX    1 mta5.am0.yahoodns.net
index 6b07cfc4feb8eb339dcf1834ab98f58165e3f16c..e9759f16a15513f13cbf5fa3462cb86589a67879 100644 (file)
@@ -574,8 +574,14 @@ manpages = [
   '8',
   ['systemd-journal-gatewayd', 'systemd-journal-gatewayd.socket'],
   'HAVE_MICROHTTPD'],
- ['systemd-journal-remote', '8', [], 'HAVE_MICROHTTPD'],
- ['systemd-journal-upload', '8', [], 'HAVE_MICROHTTPD'],
+ ['systemd-journal-remote.service',
+  '8',
+  ['systemd-journal-remote', 'systemd-journal-remote.socket'],
+  'HAVE_MICROHTTPD'],
+ ['systemd-journal-upload.service',
+  '8',
+  ['systemd-journal-upload'],
+  'HAVE_MICROHTTPD'],
  ['systemd-journald.service',
   '8',
   ['systemd-journald',
index 40edb4b4e1fe74a65f4211934ca33df9cb820d70..4ffe124905357b80db95e4591aa63222afec9065 100644 (file)
       footer with hints.</para>
     </listitem>
   </varlistentry>
+
+  <varlistentry id='cat-config'>
+    <term><option>--cat-config</option></term>
+
+    <listitem>
+      <para>Copy the contents of config files to standard output.
+      Before each file, the filename is printed as a comment.</para>
+    </listitem>
+  </varlistentry>
 </variablelist>
index 1ad395bfed54643977156128cf8736b241ecf239..b5b9bec30ed79988bf4e355f89b3a8363813bef8 100644 (file)
@@ -761,7 +761,7 @@ Sun 2017-02-26 20:57:49 EST  2h 3min left  Sun 2017-02-26 11:56:36 EST  6h ago
             <para><emphasis>NEXT</emphasis> shows the next time the timer will run.</para>
             <para><emphasis>LEFT</emphasis> shows how long till the next time the timer runs.</para>
             <para><emphasis>LAST</emphasis> shows the last time the timer ran.</para>
-            <para><emphasis>PASSED</emphasis> shows has long as passed since the timer laset ran.</para>
+            <para><emphasis>PASSED</emphasis> shows how long has passed since the timer last ran.</para>
             <para><emphasis>UNIT</emphasis> shows the name of the timer</para>
             <para><emphasis>ACTIVATES</emphasis> shows the name the service the timer activates when it runs.</para>
 
index 12d54640a911a0c5769db2651b69e684181225b8..55751ec107fb6e7e0df94939cc0e54e36cf6dacb 100644 (file)
       <arg choice="opt" rep="repeat">OPTIONS</arg>
       <arg choice="plain">dump</arg>
     </cmdsynopsis>
+    <cmdsynopsis>
+      <command>systemd-analyze</command>
+      <arg choice="opt" rep="repeat">OPTIONS</arg>
+      <arg choice="plain">cat-config</arg>
+      <arg choice="plain" rep="repeat"><replaceable>NAME</replaceable>|<replaceable>PATH</replaceable></arg>
+    </cmdsynopsis>
     <cmdsynopsis>
       <command>systemd-analyze</command>
       <arg choice="opt" rep="repeat">OPTIONS</arg>
     state. Its format is subject to change without notice and should
     not be parsed by applications.</para>
 
+    <para><command>systemd-analyze cat-config</command> is similar
+    to <command>systemctl cat</command>, but operates on config files.
+    It will copy the contents of a config file and any drop-ins to standard
+    output, using the usual systemd set of directories and rules for
+    precedence. Each argument must be either an absolute path including
+    the prefix (such as <filename>/etc/systemd/logind.conf</filename> or
+    <filename>/usr/lib/systemd/logind.conf</filename>), or a name
+    relative to the prefix (such as <filename>systemd/logind.conf</filename>).
+    </para>
+
+    <example>
+      <title>Showing logind configuration</title>
+      <programlisting>$ systemd-analyze cat-config systemd/logind.conf
+# /etc/systemd/logind.conf
+#  This file is part of systemd.
+...
+[Login]
+NAutoVTs=8
+...
+
+# /usr/lib/systemd/logind.conf.d/20-test.conf
+... some override from another package
+
+# /etc/systemd/logind.conf.d/50-override.conf
+... some adminstrator override
+      </programlisting>
+    </example>
+
     <para><command>systemd-analyze unit-paths</command> outputs a list of all
     directories from which unit files, <filename>.d</filename> overrides, and
     <filename>.wants</filename>, <filename>.requires</filename> symlinks may be
         generators enabled will generally result in some warnings.</para></listitem>
       </varlistentry>
 
+      <varlistentry>
+        <term><option>--root=<replaceable>PATH</replaceable></option></term>
+
+        <listitem><para>With <command>cat-files</command>, show config files underneath
+        the specified root path <replaceable>PATH</replaceable>.</para></listitem>
+      </varlistentry>
+
       <xi:include href="user-system-options.xml" xpointer="host" />
       <xi:include href="user-system-options.xml" xpointer="machine" />
 
index 1d9203fcff0d44672a2540ac03753b5f5e4a284f..abd936772376fe43122fbdf484312f4d781433b9 100644 (file)
       <varlistentry>
         <term><option>--no-output</option></term>
 
-       <listitem><para>Do not print passwords to standard output.
-       This is useful if you want to store a password in kernel
-       keyring with <option>--keyname</option> but do not want it
-       to show up on screen or in logs.</para></listitem>
+        <listitem><para>Do not print passwords to standard output.
+        This is useful if you want to store a password in kernel
+        keyring with <option>--keyname</option> but do not want it
+        to show up on screen or in logs.</para></listitem>
       </varlistentry>
 
       <xi:include href="standard-options.xml" xpointer="help" />
index f02e8f0cb010b3e3d30af985bf2d0e3ee2bf5ac3..37ac163f079466ae83b517842fcd2a1a4ec28902 100644 (file)
@@ -8,7 +8,8 @@
 
   Copyright 2012 Lennart Poettering
 -->
-<refentry id="systemd-binfmt.service" conditional='ENABLE_BINFMT'>
+<refentry id="systemd-binfmt.service" conditional='ENABLE_BINFMT'
+    xmlns:xi="http://www.w3.org/2001/XInclude">
 
   <refentryinfo>
     <title>systemd-binfmt.service</title>
     for information about the configuration of this service.</para>
   </refsect1>
 
+  <refsect1><title>Options</title>
+    <variablelist>
+      <xi:include href="standard-options.xml" xpointer="cat-config" />
+      <xi:include href="standard-options.xml" xpointer="help" />
+      <xi:include href="standard-options.xml" xpointer="version" />
+    </variablelist>
+  </refsect1>
+
   <refsect1>
     <title>See Also</title>
     <para>
index 5d7b6ca12a9025c91d51c3f4ef4989ef07b101d5..3ead519d07f80b130cdaa020a3546f18e8c63b01 100644 (file)
         <term><option>-r</option></term>
         <term><option>--raw</option></term>
 
-       <listitem><para>Format byte counts (as in memory usage and I/O metrics)
-       with raw numeric values rather than human-readable
+        <listitem><para>Format byte counts (as in memory usage and I/O metrics)
+        with raw numeric values rather than human-readable
         numbers.</para></listitem>
       </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 acbe54a1406c57815e02e66a2d14f7b43f8bbf81..2175c48fa284c79c9409ef805a10165bec1b3228 100644 (file)
         technology identifier.</para></listitem>
       </varlistentry>
 
+      <varlistentry>
+        <term><option>--list</option></term>
+
+        <listitem><para>Output all currently known and detectable container and VM environments.</para></listitem>
+      </varlistentry>
+
       <xi:include href="standard-options.xml" xpointer="help" />
       <xi:include href="standard-options.xml" xpointer="version" />
     </variablelist>
index ed99e7fd97d5c8e726138594e74c2df41b2b9606..fc535eb4cd5e5139474e5291a8bd42cb8e8b657d 100644 (file)
 
       <varlistentry>
         <term><option>--unescape</option></term>
+        <term><option>-u</option></term>
 
         <listitem><para>Instead of escaping the specified strings,
         undo the escaping, reversing the operation. May not be used in
 
       <varlistentry>
         <term><option>--mangle</option></term>
+        <term><option>-m</option></term>
 
         <listitem><para>Like <option>--escape</option>, but only
         escape characters that are obviously not escaped yet, and
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 14251c9823c304bf03c23d0bf2728992e1df9639..5ced52237e622c225d77ce10dcd977dfebc7eb5e 100644 (file)
     <para>
       <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
       <citerefentry><refentrytitle>journalctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
-      <citerefentry><refentrytitle>systemd-journald.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
       <citerefentry><refentrytitle>systemd.journal-fields</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
+      <citerefentry><refentrytitle>systemd-journald.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+      <citerefentry><refentrytitle>systemd-journal-remote.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+      <citerefentry><refentrytitle>systemd-journal-upload.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>
     </para>
   </refsect1>
 
similarity index 87%
rename from man/systemd-journal-remote.xml
rename to man/systemd-journal-remote.service.xml
index 1701495357937a671b7ca45e2fd87993990194f5..da7200c63a72d36293e7a905114766d3061dc951 100644 (file)
@@ -17,7 +17,7 @@
           xmlns:xi="http://www.w3.org/2001/XInclude">
 
   <refentryinfo>
-    <title>systemd-journal-remote</title>
+    <title>systemd-journal-remote.service</title>
     <productname>systemd</productname>
 
     <authorgroup>
   </refentryinfo>
 
   <refmeta>
-    <refentrytitle>systemd-journal-remote</refentrytitle>
+    <refentrytitle>systemd-journal-remote.service</refentrytitle>
     <manvolnum>8</manvolnum>
   </refmeta>
 
   <refnamediv>
+    <refname>systemd-journal-remote.service</refname>
+    <refname>systemd-journal-remote.socket</refname>
     <refname>systemd-journal-remote</refname>
     <refpurpose>Receive journal messages over the network</refpurpose>
   </refnamediv>
 
   <refsynopsisdiv>
+    <para><filename>systemd-journal-remote.service</filename></para>
+    <para><filename>systemd-journal-remote.socket</filename></para>
     <cmdsynopsis>
-      <command>systemd-journal-remote</command>
+      <command>/usr/lib/systemd/systemd-journal-remote</command>
       <arg choice="opt" rep="repeat">OPTIONS</arg>
       <arg choice="opt" rep="norepeat">-o/--output=<replaceable>DIR</replaceable>|<replaceable>FILE</replaceable></arg>
       <arg choice="opt" rep="repeat">SOURCES</arg>
   <refsect1>
     <title>Description</title>
 
-    <para>
-      <filename>systemd-journal-remote</filename> is a command to
-      receive serialized journal events and store them to the journal.
-      Input streams are in the
-      <ulink url="https://www.freedesktop.org/wiki/Software/systemd/export">
-        Journal Export Format
-      </ulink>,
-      i.e. like the output from
-      <command>journalctl --output=export</command>. For transport over
-      the network, this serialized stream is usually carried over an
-      HTTPS connection.
-    </para>
+    <para><command>systemd-journal-remote</command> is a command to receive serialized journal
+    events and store them to journal files. Input streams are in the
+    <ulink url="https://www.freedesktop.org/wiki/Software/systemd/export">Journal Export Format</ulink>,
+    i.e. like the output from <command>journalctl --output=export</command>. For transport over the
+    network, this serialized stream is usually carried over an HTTPS connection.</para>
+
+    <para><filename>systemd-journal-remote.service</filename> is a system service that uses
+    <command>systemd-journal-remote</command> to listen for connections.
+    <filename>systemd-journal-remote.socket</filename> configures the network address that
+    <filename>systemd-journal-remote.service</filename> listens on. By default this is port 19532.
+    What connections are accepted and how the received data is stored can be configured through the
+    <citerefentry><refentrytitle>journal-remote.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+    configuration file.</para>
   </refsect1>
 
   <refsect1>
         interpreted as the (negated) file descriptor number, or an
         address suitable for <option>ListenStream=</option> (c.f.
         <citerefentry><refentrytitle>systemd.socket</refentrytitle><manvolnum>5</manvolnum></citerefentry>).
-        In the first case, matching file descriptor must be inherited
-        through
+        In the first case, the server listens on port 19532 by default,
+        and the matching file descriptor must be inherited through
         <varname>$LISTEN_FDS</varname>/<varname>$LISTEN_PID</varname>.
         In the second case, an HTTP or HTTPS server will be spawned on
         this port, respectively for <option>--listen-http=</option> and
@@ -351,11 +356,11 @@ systemd-journal-remote --url http://some.host:19531/entries?boot&amp;follow
   <refsect1>
     <title>See Also</title>
     <para>
-      <citerefentry><refentrytitle>systemd-journal-upload</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+      <citerefentry><refentrytitle>journal-remote.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
       <citerefentry><refentrytitle>journalctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
-      <citerefentry><refentrytitle>systemd-journald.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
-      <citerefentry><refentrytitle>systemd-journal-gatewayd.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>
-      <citerefentry><refentrytitle>journal-remote.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+      <citerefentry><refentrytitle>systemd-journal-gatewayd.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+      <citerefentry><refentrytitle>systemd-journal-upload.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+      <citerefentry><refentrytitle>systemd-journald.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>
     </para>
   </refsect1>
 </refentry>
similarity index 87%
rename from man/systemd-journal-upload.xml
rename to man/systemd-journal-upload.service.xml
index 900706a34d640c096695bad6319f31b05c8d44c5..3f76f8755a8403992d3b318e3dca9e7498c8dd44 100644 (file)
@@ -17,7 +17,7 @@
           xmlns:xi="http://www.w3.org/2001/XInclude">
 
   <refentryinfo>
-    <title>systemd-journal-upload</title>
+    <title>systemd-journal-upload.service</title>
     <productname>systemd</productname>
 
     <authorgroup>
   </refentryinfo>
 
   <refmeta>
-    <refentrytitle>systemd-journal-upload</refentrytitle>
+    <refentrytitle>systemd-journal-upload.service</refentrytitle>
     <manvolnum>8</manvolnum>
   </refmeta>
 
   <refnamediv>
+    <refname>systemd-journal-upload.service</refname>
     <refname>systemd-journal-upload</refname>
     <refpurpose>Send journal messages over the network</refpurpose>
   </refnamediv>
 
   <refsynopsisdiv>
+    <para><filename>systemd-journal-upload.service</filename></para>
     <cmdsynopsis>
-      <command>systemd-journal-upload</command>
+      <command>/usr/lib/systemd/systemd-journal-upload</command>
       <arg choice="opt" rep="repeat">OPTIONS</arg>
       <arg choice="opt" rep="norepeat">-u/--url=<replaceable>URL</replaceable></arg>
       <arg choice="opt" rep="repeat">SOURCES</arg>
     Unless limited by one of the options specified below, all journal entries accessible to the user
     the program is running as will be uploaded, and then the program will wait and send new entries
     as they become available.</para>
+
+    <para><filename>systemd-journal-upload.service</filename> is a system service that uses
+    <command>systemd-journal-upload</command> to upload journal entries to a server. It uses the
+    configuration in
+    <citerefentry><refentrytitle>journal-upload.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>.
+    At least the <varname>URL=</varname> option must be specified.</para>
   </refsect1>
 
   <refsect1>
     <variablelist>
       <varlistentry>
         <term><option>-u</option></term>
-        <term><option>--url=<optional>https://</optional><replaceable>URL</replaceable></option></term>
-        <term><option>--url=<optional>http://</optional><replaceable>URL</replaceable></option></term>
+        <term><option>--url=<optional>https://</optional><replaceable>URL</replaceable>[:<replaceable>PORT</replaceable>]</option></term>
+        <term><option>--url=<optional>http://</optional><replaceable>URL</replaceable>[:<replaceable>PORT</replaceable>]</option></term>
 
         <listitem><para>Upload to the specified
         address. <replaceable>URL</replaceable> may specify either
         just the hostname or both the protocol and
         hostname. <constant>https</constant> is the default.
+        The port number may be specified after a colon (<literal>:</literal>),
+        otherwise <constant>19532</constant> will be used by default.
         </para></listitem>
       </varlistentry>
 
       legitimate, and vice versa, that the client is trusted.</para>
 
       <para>A suitable set of certificates can be generated with
-      <command>openssl</command>:</para>
+      <command>openssl</command>. Note, 2048 bits of key length
+      is minimally recommended to use for security reasons:</para>
 
       <programlisting>openssl req -newkey rsa:2048 -days 3650 -x509 -nodes \
       -out ca.pem -keyout ca.key -subj '/CN=Certificate authority/'
@@ -253,10 +264,10 @@ echo 0001 &gt;serial
 SERVER=server
 CLIENT=client
 
-openssl req -newkey rsa:1024 -nodes -out $SERVER.csr -keyout $SERVER.key -subj "/CN=$SERVER/"
+openssl req -newkey rsa:2048 -nodes -out $SERVER.csr -keyout $SERVER.key -subj "/CN=$SERVER/"
 openssl ca -batch -config ca.conf -notext -in $SERVER.csr -out $SERVER.pem
 
-openssl req -newkey rsa:1024 -nodes -out $CLIENT.csr -keyout $CLIENT.key -subj "/CN=$CLIENT/"
+openssl req -newkey rsa:2048 -nodes -out $CLIENT.csr -keyout $CLIENT.key -subj "/CN=$CLIENT/"
 openssl ca -batch -config ca.conf -notext -in $CLIENT.csr -out $CLIENT.pem
 </programlisting>
 
@@ -281,7 +292,8 @@ openssl ca -batch -config ca.conf -notext -in $CLIENT.csr -out $CLIENT.pem
   <refsect1>
     <title>See Also</title>
     <para>
-      <citerefentry><refentrytitle>systemd-journal-remote</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+      <citerefentry><refentrytitle>journal-upload.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+      <citerefentry><refentrytitle>systemd-journal-remote.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
       <citerefentry><refentrytitle>journalctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
       <citerefentry><refentrytitle>systemd-journald.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
       <citerefentry><refentrytitle>systemd-journal-gatewayd.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>
index 83186b4e2cc666e28bc1c71e1fa9f8cd2f3a02c7..14791a8b3fcf611065180f5588ff82dc3c9b50f7 100644 (file)
@@ -13,7 +13,7 @@
 <refentry id="systemd-networkd-wait-online.service" conditional='ENABLE_NETWORKD'>
 
   <refentryinfo>
-    <title>systemd-networkd.service</title>
+    <title>systemd-networkd-wait-online.service</title>
     <productname>systemd</productname>
 
     <authorgroup>
@@ -46,7 +46,7 @@
     <title>Description</title>
 
     <para><command>systemd-networkd-wait-online</command> is a
-    one-shot system service that waits for the network to be
+    oneshot system service (see <citerefentry><refentrytitle>systemd.service</refentrytitle><manvolnum>5</manvolnum></citerefentry>), that waits for the network to be
     configured. By default, it will wait for all links it is aware of
     and which are managed by
     <citerefentry><refentrytitle>systemd-networkd.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>
@@ -92,6 +92,7 @@
     <title>See Also</title>
     <para>
       <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+      <citerefentry><refentrytitle>systemd.service</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
       <citerefentry><refentrytitle>systemd-networkd.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>
     </para>
   </refsect1>
index 1948b0a802bc25b39d3f3403a92dacc52d4f8678..1c8c6c8e60bb5e2548c9e6da08a7928baf3bf3d1 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>
         <option>--link-journal=try-guest</option>.</para></listitem>
       </varlistentry>
 
+      <varlistentry>
+        <term><option>--resolv-conf=</option></term>
+
+        <listitem><para>Configures how <filename>/etc/resolv.conf</filename> inside of the container (i.e. DNS
+        configuration synchronization from host to container) shall be handled. Takes one of <literal>off</literal>,
+        <literal>copy-host</literal>, <literal>copy-static</literal>, <literal>bind-host</literal>,
+        <literal>bind-static</literal>, <literal>delete</literal> or <literal>auto</literal>. If set to
+        <literal>off</literal> the <filename>/etc/resolv.conf</filename> file in the container is left as it is
+        included in the image, and neither modified nor bind mounted over. If set to <literal>copy-host</literal>, the
+        <filename>/etc/resolv.conf</filename> file from the host is copied into the container. Similar, if
+        <literal>bind-host</literal> is used, the file is bind mounted from the host into the container. If set to
+        <literal>copy-static</literal> the static <filename>resolv.conf</filename> file supplied with
+        <citerefentry><refentrytitle>systemd-resolved.service</refentrytitle><manvolnum>8</manvolnum></citerefentry> is
+        copied into the container, and correspondingly <literal>bind-static</literal> bind mounts it there. If set to
+        <literal>delete</literal> the <filename>/etc/resolv.conf</filename> file in the container is deleted if it
+        exists. Finally, if set to <literal>auto</literal> the file is left as it is if private networking is turned on
+        (see <option>--private-network</option>). Otherwise, if <filename>systemd-resolved.service</filename> is
+        connectible its static <filename>resolv.conf</filename> file is used, and if not the host's
+        <filename>/etc/resolv.conf</filename> file is used. In the latter cases the file is copied if the image is
+        writable, and bind mounted otherwise. It's recommended to use <literal>copy</literal> if the container shall be
+        able to make changes to the DNS configuration on its own, deviating from the host's settings. Otherwise
+        <literal>bind</literal> is preferable, as it means direct changes to <filename>/etc/resolv.conf</filename> in
+        the container are not allowed, as it is a read-only bind mount (but note that if the container has enough
+        privileges, it might simply go ahead and unmount the bind mount anyway). Note that both if the file is bind
+        mounted and if it is copied no further propagation of configuration is generally done after the one-time early
+        initialization (this is because the file is usually updated through copying and renaming). Defaults to
+        <literal>auto</literal>.</para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><option>--timezone=</option></term>
+
+        <listitem><para>Configures how <filename>/etc/localtime</filename> inside of the container (i.e. local timezone
+        synchronization from host to container) shall be handled. Takes one of <literal>off</literal>,
+        <literal>copy</literal>, <literal>bind</literal>, <literal>symlink</literal>, <literal>delete</literal> or
+        <literal>auto</literal>. If set to <literal>off</literal> the <filename>/etc/localtime</filename> file in the
+        container is left as it is included in the image, and neither modified nor bind mounted over. If set to
+        <literal>copy</literal> the <filename>/etc/localtime</filename> file of the host is copied into the
+        container. Similar, if <literal>bind</literal> is used, it is bind mounted from the host into the container. If
+        set to <literal>symlink</literal> a symlink from <filename>/etc/localtime</filename> in the container is
+        created pointing to the matching the timezone file of the container that matches the timezone setting on the
+        host. If set to <literal>delete</literal> the file in the container is deleted, should it exist. If set to
+        <literal>auto</literal> and the <filename>/etc/localtime</filename> file of the host is a symlink, then
+        <literal>symlink</literal> mode is used, and <literal>copy</literal> otherwise, except if the image is
+        read-only in which case <literal>bind</literal> is used instead. Defaults to
+        <literal>auto</literal>.</para></listitem>
+      </varlistentry>
+
       <varlistentry>
         <term><option>--read-only</option></term>
 
index b4fdc708ad4ca4f5a6a27cc12b8209ac831fe75a..5df310cff561b047b1c3ffb3ef372d4515440ad4 100644 (file)
@@ -79,6 +79,7 @@
         </listitem>
       </varlistentry>
 
+      <xi:include href="standard-options.xml" xpointer="cat-config" />
       <xi:include href="standard-options.xml" xpointer="help" />
       <xi:include href="standard-options.xml" xpointer="version" />
 
index 0f4a47bc7e831b3550dd61b2967eb0451cfda67f..ea119fe375297f52b298c18f0f28aa42202abd12 100644 (file)
         line instead of a file name.</para></listitem>
       </varlistentry>
 
+      <xi:include href="standard-options.xml" xpointer="cat-config" />
       <xi:include href="standard-options.xml" xpointer="help" />
       <xi:include href="standard-options.xml" xpointer="version" />
     </variablelist>
index c40f8a920a0ac3ccb0aa7ebb9e0102a84cef28d0..3ef3fa28706f9829b1349f5fa402d8e8a67f4145 100644 (file)
         </para></listitem>
       </varlistentry>
 
+      <xi:include href="standard-options.xml" xpointer="cat-config" />
       <xi:include href="standard-options.xml" xpointer="help" />
       <xi:include href="standard-options.xml" xpointer="version" />
     </variablelist>
     <filename>/usr/include/sysexits.h</filename>). If the configuration was syntactically valid, but
     could not be executed (lack of permissions, creation of files in missing directories, invalid
     contents when writing to <filename>/sys/</filename> values, …), <constant>73</constant> is
-    returned (<constant>EX_DATAERR</constant> from <filename>/usr/include/sysexits.h</filename>).
+    returned (<constant>EX_CANTCREAT</constant> from <filename>/usr/include/sysexits.h</filename>).
     Otherwise, <constant>1</constant> is returned (<constant>EXIT_FAILURE</constant> from
     <filename>/usr/include/stdlib.h</filename>).
     </para>
index f26a0755ecee41b9f299526aab04a7f6a128479f..b21c5aa104b1af27bea24482772c5ee67bd35c60 100644 (file)
@@ -1703,8 +1703,8 @@ RestrictNamespaces=~cgroup net</programlisting>
 
         <para>The <option>file:<replaceable>path</replaceable></option> option may be used to connect a specific file
         system object to standard output. The semantics are similar to the same option of
-        <varname>StandardInputText=</varname>, see above. If standard input and output are directed to the same file
-        path, it is opened only once, for reading as well as writing and duplicated. This is particular useful when the
+        <varname>StandardInput=</varname>, see above. If standard input and output are directed to the same file path,
+        it is opened only once, for reading as well as writing and duplicated. This is particular useful when the
         specified path refers to an <constant>AF_UNIX</constant> socket in the file system, as in that case only a
         single stream connection is created for both input and output.</para>
 
index c7c920913b373aada3eb36064a1e08228d2749f3..dbe625762340f642f31c7838d09f54a3807ba29c 100644 (file)
       <varlistentry>
         <term><varname>MACAddress=</varname></term>
         <listitem>
-          <para>The hardware address.</para>
+          <para>A whitespace-separated list of hardware addresses. Use full colon-, hyphen- or dot-delimited hexadecimal. See the example below.
+          This option may appear more than once, in which case the lists are merged. If the empty string is assigned to this option, the list
+          of hardware addresses defined prior to this is reset.</para>
+
+          <para>Example:
+          <programlisting>MACAddress=01:23:45:67:89:ab 00-11-22-33-44-55 AABB.CCDD.EEFF</programlisting></para>
         </listitem>
       </varlistentry>
       <varlistentry>
           Defaults to "unset".</para>
         </listitem>
       </varlistentry>
+      <varlistentry>
+        <term><varname>RxChannels=</varname></term>
+        <listitem>
+          <para>Sets the number of receive channels (a number between 1 and 4294967295) .</para>
+        </listitem>
+      </varlistentry>
+      <varlistentry>
+        <term><varname>TxChannels=</varname></term>
+        <listitem>
+          <para>Sets the number of transmit channels (a number between 1 and 4294967295).</para>
+        </listitem>
+      </varlistentry>
+      <varlistentry>
+        <term><varname>OtherChannels=</varname></term>
+        <listitem>
+          <para>Sets the number of other channels (a number between 1 and 4294967295).</para>
+        </listitem>
+      </varlistentry>
+      <varlistentry>
+        <term><varname>CombinedChannels=</varname></term>
+        <listitem>
+          <para>Sets the number of combined set channels (a number between 1 and 4294967295).</para>
+        </listitem>
+      </varlistentry>
     </variablelist>
   </refsect1>
 
index 55db523e79c10490d1268746022a4205a4f1e893..82629b917252ba2ac782da7654ad0b4aa3f00aae 100644 (file)
         <varlistentry>
           <term><varname>MACAddress=</varname></term>
           <listitem>
-            <para>The hardware address of the interface (use full colon-delimited hexadecimal, e.g.,
-            01:23:45:67:89:ab).</para>
+            <para>A whitespace-separated list of hardware addresses. Use full colon-, hyphen- or dot-delimited hexadecimal. See the example below.
+            This option may appear more than one, in which case the lists are merged. If the empty string is assigned to this option, the list
+            of hardware addresses defined prior to this is reset.</para>
+
+            <para>Example:
+            <programlisting>MACAddress=01:23:45:67:89:ab 00-11-22-33-44-55 AABB.CCDD.EEFF</programlisting></para>
           </listitem>
         </varlistentry>
         <varlistentry>
             </para>
           </listitem>
         </varlistentry>
-
+        <varlistentry>
+        <term><varname>MTUBytes=</varname></term>
+        <listitem>
+          <para>The maximum transmission unit in bytes to set for the
+          route. The usual suffixes K, M, G, are supported and are
+          understood to the base of 1024.</para>
+          <para>Note that if IPv6 is enabled on the interface, and the MTU is chosen
+          below 1280 (the minimum MTU for IPv6) it will automatically be increased to this value.</para>
+        </listitem>
+      </varlistentry>
       </variablelist>
   </refsect1>
 
           </listitem>
         </varlistentry>
 
+        <varlistentry>
+          <term><varname>UserClass=</varname></term>
+          <listitem>
+            <para>A DHCPv4 client can use UserClass option to identify the type or category of user or applications
+            it represents. The information contained in this option is a string that represents the user class of which
+            the client is a member. Each class sets an identifying string of information to be used by the DHCP
+            service to classify clients. Takes a whitespace-separated list of strings.</para>
+          </listitem>
+        </varlistentry>
+
         <varlistentry>
           <term><varname>DUIDType=</varname></term>
           <listitem>
index b5c60a33e0b0ac2f2b642f80b0bdb7400511e14f..275f96ca138bc288a165121b69c7b96051fc7113 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>
+
+      <varlistentry>
+        <term><varname>ResolvConf=</varname></term>
+
+        <listitem><para>Configures how <filename>/etc/resolv.conf</filename> in the container shall be handled. This is
+        equivalent to the <option>--resolv-conf=</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>Timezone=</varname></term>
+
+        <listitem><para>Configures how <filename>/etc/localtime</filename> in the container shall be handled. This is
+        equivalent to the <option>--localtime=</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>LinkJournal=</varname></term>
+
+        <listitem><para>Configures how to link host and container journal setups. This is equivalent to the
+        <option>--link-journal=</option> command line switch, and takes the same parameter. See
+        <citerefentry><refentrytitle>systemd-nspawn</refentrytitle><manvolnum>1</manvolnum></citerefentry> for
+        details.</para></listitem>
+      </varlistentry>
+
     </variablelist>
   </refsect1>
 
index 03c7b01b3bb6861d56226cc0daeaa500b9b73124..4533469d9b8ff89febc87d305def718af33f2708 100644 (file)
         must occur before <varname>RuntimeMaxSec=</varname> is exceeded, and once the runtime has exended beyond
         <varname>RuntimeMaxSec=</varname>, the service manager will allow the service to continue to run, provided
         the service repeats <literal>EXTEND_TIMEOUT_USEC=…</literal> within the interval specified until the service
-        shutdown is acheived by <literal>STOPPING=1</literal> (or termination). (see
+        shutdown is achieved by <literal>STOPPING=1</literal> (or termination). (see
         <citerefentry><refentrytitle>sd_notify</refentrytitle><manvolnum>3</manvolnum></citerefentry>).
         </para></listitem>
       </varlistentry>
         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 4f96c3c4e68470aee16700a1005b431c9487f067..23be82d9d28c397c99f72fc34d93bee781dc5d8d 100644 (file)
           functionality to other hosts generally do not need to pull
           this in.</para>
 
+          <para>systemd automatically adds dependencies of type <varname>Wants=</varname> and <varname>After=</varname>
+          for this target unit to all SysV init script service units with an LSB header referring to the
+          <literal>$network</literal> facility.</para>
+
           <para>Note that this unit is only useful during the original system start-up logic. After the system has
           completed booting up, it will not track the online state of the system anymore. Due to this it cannot be used
           as a network connection monitor concept, it is purely a one-time system start-up concept.</para>
           information. Also see
           <filename>network-online.target</filename> described
           above.</para>
-
-          <para>systemd automatically adds dependencies of type
-          <varname>After=</varname> for this target unit to all SysV
-          init script service units with an LSB header referring to
-          the <literal>$network</literal> facility.</para>
         </listitem>
       </varlistentry>
       <varlistentry>
       <varlistentry>
         <term><filename>nss-lookup.target</filename></term>
         <listitem>
-          <para>A target that should be used as synchronization point
-          for all host/network name service lookups. Note that this is
-          independent of user/group name lookups for which
-          <filename>nss-user-lookup.target</filename> should be used.
-          All services for which the availability of full host/network
-          name resolution is essential should be ordered after this
-          target, but not pull it in. systemd automatically adds
-          dependencies of type <varname>After=</varname> for this
-          target unit to all SysV init script service units with an
-          LSB header referring to the <literal>$named</literal>
-          facility.</para>
+          <para>A target that should be used as synchronization point for all host/network name service lookups. Note
+          that this is independent of UNIX user/group name lookups for which <filename>nss-user-lookup.target</filename>
+          should be used.  All services for which the availability of full host/network name resolution is essential
+          should be ordered after this target, but not pull it in. systemd automatically adds dependencies of type
+          <varname>After=</varname> for this target unit to all SysV init script service units with an LSB header
+          referring to the <literal>$named</literal> facility.</para>
         </listitem>
       </varlistentry>
       <varlistentry>
         <term><filename>nss-user-lookup.target</filename></term>
         <listitem>
-          <para>A target that should be used as synchronization point
-          for all user/group name service lookups. Note that this is
-          independent of host/network name lookups for which
-          <filename>nss-lookup.target</filename> should be used. All
-          services for which the availability of the full user/group
-          database is essential should be ordered after this target,
-          but not pull it in. Note that system users are always
-          resolvable, and hence do not require any special ordering
-          against this target.</para>
+          <para>A target that should be used as synchronization point for all regular UNIX user/group name service
+          lookups. Note that this is independent of host/network name lookups for which
+          <filename>nss-lookup.target</filename> should be used. All services for which the availability of the full
+          user/group database is essential should be ordered after this target, but not pull it in. All services which
+          provide parts of the user/group database should be ordered before this target, and pull it in. Note that this
+          unit is only relevant for regular users and groups — system users and groups are required to be resolvable
+          during earliest boot already, and hence do not need any special ordering against this target.</para>
         </listitem>
       </varlistentry>
       <varlistentry>
index 02e0f499e8a08217b1cded6580c208fe11d5f859..73a0462a2b0f40f503b0620b4771cdf1d5ea0003 100644 (file)
     <para>The set of load paths for the user manager instance may be augmented or
     changed using various environment variables. And environment variables may in
     turn be set using environment generators, see
-    <citerefentry><refentrytitle>system.environment-generator</refentrytitle><manvolnum>7</manvolnum></citerefentry>.
+    <citerefentry><refentrytitle>systemd.environment-generator</refentrytitle><manvolnum>7</manvolnum></citerefentry>.
     In particular, <varname>$XDG_DATA_HOME</varname> and
     <varname>$XDG_DATA_DIRS</varname> may be easily set using
     <citerefentry><refentrytitle>systemd-environment-d-generator</refentrytitle><manvolnum>8</manvolnum></citerefentry>.
index 4dd4776c06dd10cb7d9c9a4ca5e7c88bca0625e2..3a862f540b784429dde4e0a0efd3fdf4de8bfd1c 100644 (file)
@@ -78,7 +78,8 @@
         <term><option>-d</option></term>
         <term><option>--debug</option></term>
         <listitem>
-          <para>Print debug messages to standard error.</para>
+          <para>Print debug messages to standard error. This option is implied in <command>udevadm test</command> and
+          <command>udevadm test-builtin</command> commands.</para>
         </listitem>
       </varlistentry>
 
             <filename><optional>/sys</optional>/class/block/sda</filename>.
             Note that this option usually is not very useful, since
             <command>udev</command> can guess the type of the
-            argument, so <command>udevadm
-            --devpath=/class/block/sda</command> is equivalent to
-            <command>udevadm /sys/class/block/sda</command>.</para>
+            argument, so <command>udevadm info
+            --path=/class/block/sda</command> is equivalent to
+            <command>udevadm info /sys/class/block/sda</command>.</para>
           </listitem>
         </varlistentry>
         <varlistentry>
             e.g. <filename><optional>/dev</optional>/sda</filename>.
             Note that this option usually is not very useful, since
             <command>udev</command> can guess the type of the
-            argument, so <command>udevadm --name=sda</command> is
-            equivalent to <command>udevadm /dev/sda</command>.</para>
+            argument, so <command>udevadm info --name=sda</command> is
+            equivalent to <command>udevadm info /dev/sda</command>.</para>
           </listitem>
         </varlistentry>
         <varlistentry>
           <term><option>-y</option></term>
           <term><option>--sysname-match=<replaceable>PATH</replaceable></option></term>
           <listitem>
-           <para>Trigger events for devices for which the last component
-           (i.e. the filename) of the <filename>/sys</filename> path matches
-           the specified <replaceable>PATH</replaceable>. This option can be
-           specified multiple times and also supports shell style pattern
-           matching.</para>
+            <para>Trigger events for devices for which the last component
+            (i.e. the filename) of the <filename>/sys</filename> path matches
+            the specified <replaceable>PATH</replaceable>. This option can be
+            specified multiple times and also supports shell style pattern
+            matching.</para>
           </listitem>
         </varlistentry>
         <varlistentry>
index 3fa4f7f3271cd1aa97c365e4b7630c729f4d9407..ca8ffabee2766322f1314f6edb2e9370d0677fa2 100644 (file)
@@ -11,13 +11,13 @@ project('systemd', 'c',
                 'sysconfdir=/etc',
                 'localstatedir=/var',
         ],
-        meson_version : '>= 0.41',
+        meson_version : '>= 0.44',
        )
 
 libsystemd_version = '0.22.0'
 libudev_version = '1.6.10'
 
-# We need the same data in three different formats, ugh!
+# We need the same data in two different formats, ugh!
 # Also, for hysterical reasons, we use different variable
 # names, sometimes. Not all variables are included in every
 # set. Ugh, ugh, ugh!
@@ -29,8 +29,6 @@ substs = configuration_data()
 substs.set('PACKAGE_URL',          'https://www.freedesktop.org/wiki/Software/systemd')
 substs.set('PACKAGE_VERSION',      meson.project_version())
 
-m4_defines = []
-
 #####################################################################
 
 # Try to install the git pre-commit hook
@@ -67,10 +65,8 @@ endif
 
 sysvinit_path = get_option('sysvinit-path')
 sysvrcnd_path = get_option('sysvrcnd-path')
-have = sysvinit_path != '' and sysvrcnd_path != ''
-conf.set10('HAVE_SYSV_COMPAT', have,
+conf.set10('HAVE_SYSV_COMPAT', sysvinit_path != '' and sysvrcnd_path != '',
            description : 'SysV init scripts and rcN.d links are supported')
-m4_defines += have ? ['-DHAVE_SYSV_COMPAT'] : []
 
 # join_paths ignore the preceding arguments if an absolute component is
 # encountered, so this should canonicalize various paths when they are
@@ -245,12 +241,14 @@ substs.set('userpresetdir',                                   userpresetdir)
 substs.set('udevhwdbdir',                                     udevhwdbdir)
 substs.set('udevrulesdir',                                    udevrulesdir)
 substs.set('udevlibexecdir',                                  udevlibexecdir)
+substs.set('environmentdir',                                  environmentdir)
 substs.set('catalogdir',                                      catalogdir)
 substs.set('tmpfilesdir',                                     tmpfilesdir)
 substs.set('sysusersdir',                                     sysusersdir)
 substs.set('sysctldir',                                       sysctldir)
 substs.set('binfmtdir',                                       binfmtdir)
 substs.set('modulesloaddir',                                  modulesloaddir)
+substs.set('modprobedir',                                     modprobedir)
 substs.set('systemgeneratordir',                              systemgeneratordir)
 substs.set('usergeneratordir',                                usergeneratordir)
 substs.set('systemenvgeneratordir',                           systemenvgeneratordir)
@@ -295,55 +293,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',
@@ -370,53 +389,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'
 
 #####################################################################
@@ -698,18 +682,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
 
@@ -717,24 +701,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)
@@ -754,13 +738,8 @@ else
 endif
 substs.set('USERS_GID', users_gid)
 
-if get_option('adm-group')
-        m4_defines += ['-DENABLE_ADM_GROUP']
-endif
-
-if get_option('wheel-group')
-        m4_defines += ['-DENABLE_WHEEL_GROUP']
-endif
+conf.set10('ENABLE_ADM_GROUP', get_option('adm-group'))
+conf.set10('ENABLE_WHEEL_GROUP', get_option('wheel-group'))
 
 substs.set('DEV_KVM_MODE', get_option('dev-kvm-mode'))
 substs.set('GROUP_RENDER_MODE', get_option('group-render-mode'))
@@ -783,23 +762,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')
@@ -828,7 +806,6 @@ else
         libseccomp = []
 endif
 conf.set10('HAVE_SECCOMP', have)
-m4_defines += have ? ['-DHAVE_SECCOMP'] : []
 
 want_selinux = get_option('selinux')
 if want_selinux != 'false' and not fuzzer_build
@@ -841,7 +818,6 @@ else
         libselinux = []
 endif
 conf.set10('HAVE_SELINUX', have)
-m4_defines += have ? ['-DHAVE_SELINUX'] : []
 
 want_apparmor = get_option('apparmor')
 if want_apparmor != 'false' and not fuzzer_build
@@ -853,12 +829,10 @@ else
         libapparmor = []
 endif
 conf.set10('HAVE_APPARMOR', have)
-m4_defines += have ? ['-DHAVE_APPARMOR'] : []
 
 smack_run_label = get_option('smack-run-label')
 if smack_run_label != ''
         conf.set_quoted('SMACK_RUN_LABEL', smack_run_label)
-        m4_defines += ['-DHAVE_SMACK_RUN_LABEL']
 endif
 
 want_polkit = get_option('polkit')
@@ -885,7 +859,6 @@ else
         libacl = []
 endif
 conf.set10('HAVE_ACL', have)
-m4_defines += have ? ['-DHAVE_ACL'] : []
 
 want_audit = get_option('audit')
 if want_audit != 'false' and not fuzzer_build
@@ -930,7 +903,6 @@ else
         libpam_misc = []
 endif
 conf.set10('HAVE_PAM', have)
-m4_defines += have ? ['-DHAVE_PAM'] : []
 
 want_microhttpd = get_option('microhttpd')
 if want_microhttpd != 'false' and not fuzzer_build
@@ -943,7 +915,6 @@ else
         libmicrohttpd = []
 endif
 conf.set10('HAVE_MICROHTTPD', have)
-m4_defines += have ? ['-DHAVE_MICROHTTPD'] : []
 
 want_libcryptsetup = get_option('libcryptsetup')
 if want_libcryptsetup != 'false' and not fuzzer_build
@@ -968,7 +939,6 @@ else
         libcurl = []
 endif
 conf.set10('HAVE_LIBCURL', have)
-m4_defines += have ? ['-DHAVE_LIBCURL'] : []
 
 want_libidn = get_option('libidn')
 want_libidn2 = get_option('libidn2')
@@ -985,7 +955,6 @@ else
         libidn = []
 endif
 conf.set10('HAVE_LIBIDN', have)
-m4_defines += have ? ['-DHAVE_LIBIDN'] : []
 if not have and want_libidn2 != 'false' and not fuzzer_build
         # libidn is used for both libidn and libidn2 objects
         libidn = dependency('libidn2',
@@ -995,7 +964,6 @@ else
         have = false
 endif
 conf.set10('HAVE_LIBIDN2', have)
-m4_defines += have ? ['-DHAVE_LIBIDN2'] : []
 
 want_libiptc = get_option('libiptc')
 if want_libiptc != 'false' and not fuzzer_build
@@ -1007,7 +975,6 @@ else
         libiptc = []
 endif
 conf.set10('HAVE_LIBIPTC', have)
-m4_defines += have ? ['-DHAVE_LIBIPTC'] : []
 
 want_qrencode = get_option('qrencode')
 if want_qrencode != 'false' and not fuzzer_build
@@ -1234,15 +1201,9 @@ foreach term : ['utmp',
         have = get_option(term)
         name = 'ENABLE_' + term.underscorify().to_upper()
         conf.set10(name, have)
-        m4_defines += have ? ['-D' + name] : []
 endforeach
 
-if get_option('timedated') or get_option('timesyncd')
-        conf.set10('ENABLE_TIMEDATECTL', true)
-        m4_defines += ['-DENABLE_TIMEDATECTL']
-else
-        conf.set10('ENABLE_TIMEDATECTL', false)
-endif
+conf.set10('ENABLE_TIMEDATECTL', get_option('timedated') or get_option('timesyncd'))
 
 want_tests = get_option('tests')
 install_tests = get_option('install-tests')
@@ -1289,6 +1250,8 @@ config_h = configure_file(
         output : 'config.h',
         configuration : conf)
 
+meson_apply_m4 = find_program('tools/meson-apply-m4.sh')
+
 includes = include_directories('src/basic',
                                'src/shared',
                                'src/systemd',
@@ -1347,6 +1310,31 @@ libsystemd = shared_library(
         install : true,
         install_dir : rootlibdir)
 
+static_libsystemd = get_option('static-libsystemd')
+static_libsystemd_pic = static_libsystemd == 'true' or static_libsystemd == 'pic'
+
+install_libsystemd_static = static_library(
+        'systemd',
+        libsystemd_sources,
+        journal_client_sources,
+        basic_sources,
+        basic_gcrypt_sources,
+        include_directories : includes,
+        build_by_default : static_libsystemd != 'false',
+        install : static_libsystemd != 'false',
+        install_dir : rootlibdir,
+        pic : static_libsystemd == 'true' or static_libsystemd == 'pic',
+        dependencies : [threads,
+                        librt,
+                        libxz,
+                        liblz4,
+                        libcap,
+                        libblkid,
+                        libmount,
+                        libselinux,
+                        libgcrypt],
+        c_args : libsystemd_c_args + (static_libsystemd_pic ? [] : ['-fno-PIC']))
+
 ############################################################
 
 # binaries that have --help and are intended for use by humans,
@@ -2546,17 +2534,30 @@ foreach tuple : tests
         endif
 endforeach
 
-test_libsystemd_sym = executable(
+exe = executable(
         'test-libsystemd-sym',
         test_libsystemd_sym_c,
         include_directories : includes,
         link_with : [libsystemd],
         install : install_tests,
         install_dir : testsdir)
-test('test-libsystemd-sym',
-     test_libsystemd_sym)
+test('test-libsystemd-sym', exe)
+
+exe = executable(
+        'test-libsystemd-static-sym',
+        test_libsystemd_sym_c,
+        include_directories : includes,
+        link_with : [install_libsystemd_static],
+        dependencies : [threads], # threads is already included in dependencies on the library,
+                                  # but does not seem to get propagated. Add here as a work-around.
+        build_by_default : static_libsystemd_pic,
+        install : install_tests and static_libsystemd_pic,
+        install_dir : testsdir)
+if static_libsystemd_pic
+        test('test-libsystemd-static-sym', exe)
+endif
 
-test_libudev_sym = executable(
+exe = executable(
         'test-libudev-sym',
         test_libudev_sym_c,
         include_directories : includes,
@@ -2564,8 +2565,20 @@ test_libudev_sym = executable(
         link_with : [libudev],
         install : install_tests,
         install_dir : testsdir)
-test('test-libudev-sym',
-     test_libudev_sym)
+test('test-libudev-sym', exe)
+
+exe = executable(
+        'test-libudev-static-sym',
+        test_libudev_sym_c,
+        include_directories : includes,
+        c_args : ['-Wno-deprecated-declarations'],
+        link_with : [install_libudev_static],
+        build_by_default : static_libudev_pic,
+        install : install_tests and static_libudev_pic,
+        install_dir : testsdir)
+if static_libudev_pic
+        test('test-libudev-static-sym', exe)
+endif
 
 ############################################################
 
@@ -2724,9 +2737,8 @@ if git.found()
                 'tags',
                 output : 'tags',
                 command : [env, 'etags', '-o', '@0@/TAGS'.format(meson.current_source_dir())] + all_files)
-        custom_target(
+        run_target(
                 'ctags',
-                output : 'ctags',
                 command : [env, 'ctags', '-o', '@0@/tags'.format(meson.current_source_dir())] + all_files)
 endif
 
@@ -2916,6 +2928,7 @@ foreach tuple : [
         ['gshadow'],
         ['debug hashmap'],
         ['debug mmap cache'],
+        ['valgrind',         conf.get('VALGRIND') == 1],
 ]
 
         if tuple.length() >= 2
@@ -2941,8 +2954,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 a6ea6c498f6da4510c27c821781b1de554ad6702..e3dea3ebc5413fa9c7e6130f182b1c10ceb13955 100644 (file)
@@ -13,6 +13,12 @@ option('rootprefix', type : 'string',
        description : '''override the root prefix''')
 option('link-udev-shared', type : 'boolean',
        description : 'link systemd-udev and its helpers to libsystemd-shared.so')
+option('static-libsystemd', type : 'combo',
+       choices : ['false', 'true', 'pic', 'no-pic'],
+       description : '''install a static library for libsystemd''')
+option('static-libudev', type : 'combo',
+       choices : ['false', 'true', 'pic', 'no-pic'],
+       description : '''install a static library for libudev''')
 
 option('sysvinit-path', type : 'string', value : '/etc/init.d',
        description : 'the directory where the SysV init scripts are located')
@@ -40,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 31e5f55beb8be78315b1d69b865ae2d3685dea40..be02ee49610d1d2e6eb1e3e62cb2ce68d6e81762 100644 (file)
--- a/po/uk.po
+++ b/po/uk.po
@@ -1,16 +1,15 @@
 # SPDX-License-Identifier: LGPL-2.1+
-#
 # Ukrainian translation for systemd.
 # Copyright (C) 2014 systemd's COPYRIGHT HOLDER
 # This file is distributed under the same license as the systemd package.
 # Eugene Melnik <jeka7js@gmail.com>, 2014.
-# Daniel Korostil <ted.korostiled@gmail.com>, 2014, 2016.
+# Daniel Korostil <ted.korostiled@gmail.com>, 2014, 2016, 2018.
 msgid ""
 msgstr ""
 "Project-Id-Version: systemd master\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2016-01-11 09:21+0200\n"
-"PO-Revision-Date: 2016-01-11 11:00+0300\n"
+"Report-Msgid-Bugs-To: https://github.com/systemd/systemd/issues\n"
+"POT-Creation-Date: 2018-03-27 03:26+0000\n"
+"PO-Revision-Date: 2018-05-11 23:16+0300\n"
 "Last-Translator: Daniel Korostil <ted.korostiled@gmail.com>\n"
 "Language-Team: linux.org.ua\n"
 "Language: uk\n"
@@ -21,551 +20,623 @@ msgstr ""
 "n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
 "X-Generator: Virtaal 0.7.1\n"
 
-#: ../src/core/org.freedesktop.systemd1.policy.in.in.h:1
+#: src/core/org.freedesktop.systemd1.policy.in:22
 msgid "Send passphrase back to system"
 msgstr "Надіслати пароль назад у систему"
 
-#: ../src/core/org.freedesktop.systemd1.policy.in.in.h:2
+#: src/core/org.freedesktop.systemd1.policy.in:23
 msgid ""
 "Authentication is required to send the entered passphrase back to the system."
-msgstr "Ð\97аÑ\81вÑ\96дÑ\87еннÑ\8f Ð¿Ð¾Ñ\82Ñ\80Ñ\96бно, щоб надіслати введений пароль назад у систему."
+msgstr "Ð\9fоÑ\82Ñ\80Ñ\96бна Ð°Ð²Ñ\82енÑ\82иÑ\84Ñ\96каÑ\86Ñ\96Ñ\8f, щоб надіслати введений пароль назад у систему."
 
-#: ../src/core/org.freedesktop.systemd1.policy.in.in.h:3
+#: src/core/org.freedesktop.systemd1.policy.in:33
 msgid "Manage system services or other units"
-msgstr "Керувати системними службами й іншими одиницями"
+msgstr "Керувати системними службами й іншими одиницями systemd"
 
-#: ../src/core/org.freedesktop.systemd1.policy.in.in.h:4
+#: src/core/org.freedesktop.systemd1.policy.in:34
 msgid "Authentication is required to manage system services or other units."
 msgstr ""
-"Ð\97аÑ\81вÑ\96дÑ\87еннÑ\8f Ð¿Ð¾Ñ\82Ñ\80Ñ\96бно, Ñ\89об ÐºÐµÑ\80Ñ\83ваÑ\82и Ñ\81иÑ\81Ñ\82емними Ñ\81лÑ\83жбами Ð¹ Ñ\96нÑ\88ими Ð¾Ð´Ð¸Ð½Ð¸Ñ\86Ñ\8fми."
+"Ð\9fоÑ\82Ñ\80Ñ\96бна Ð°Ð²Ñ\82енÑ\82иÑ\84Ñ\96каÑ\86Ñ\96Ñ\8f, Ñ\89об ÐºÐµÑ\80Ñ\83ваÑ\82и Ñ\81иÑ\81Ñ\82емними Ñ\81лÑ\83жбами Ð¹ Ñ\96нÑ\88ими Ð¾Ð´Ð¸Ð½Ð¸Ñ\86Ñ\8fми systemd."
 
-#: ../src/core/org.freedesktop.systemd1.policy.in.in.h:5
+#: src/core/org.freedesktop.systemd1.policy.in:43
 msgid "Manage system service or unit files"
-msgstr "Керувати системними службами й файлами одиниць"
+msgstr "Керувати системними службами й одиницями systemd"
 
-#: ../src/core/org.freedesktop.systemd1.policy.in.in.h:6
+#: src/core/org.freedesktop.systemd1.policy.in:44
 msgid "Authentication is required to manage system service or unit files."
 msgstr ""
-"Ð\97аÑ\81вÑ\96дÑ\87еннÑ\8f Ð¿Ð¾Ñ\82Ñ\80Ñ\96бно, Ñ\89об ÐºÐµÑ\80Ñ\83ваÑ\82и Ñ\81иÑ\81Ñ\82емними Ñ\81лÑ\83жбами Ð¹ Ñ\84айлами Ð¾Ð´Ð¸Ð½Ð¸Ñ\86Ñ\8c."
+"Ð\9fоÑ\82Ñ\80Ñ\96бна Ð°Ð²Ñ\82енÑ\82иÑ\84Ñ\96каÑ\86Ñ\96Ñ\8f, Ñ\89об ÐºÐµÑ\80Ñ\83ваÑ\82и Ñ\81иÑ\81Ñ\82емними Ñ\81лÑ\83жбами Ð¹ Ð¾Ð´Ð¸Ð½Ð¸Ñ\86Ñ\8fми systemd."
 
-#: ../src/core/org.freedesktop.systemd1.policy.in.in.h:7
+#: src/core/org.freedesktop.systemd1.policy.in:53
 msgid "Set or unset system and service manager environment variables"
 msgstr ""
 "Встановити або забрати змінну середовища з керування службами і системою"
 
-#: ../src/core/org.freedesktop.systemd1.policy.in.in.h:8
+#: src/core/org.freedesktop.systemd1.policy.in:54
 msgid ""
 "Authentication is required to set or unset system and service manager "
 "environment variables."
 msgstr ""
-"Ð\97аÑ\81вÑ\96дÑ\87еннÑ\8f Ð¿Ð¾Ñ\82Ñ\80Ñ\96бно, щоб установити або забрати змінні середовища з "
+"Ð\9fоÑ\82Ñ\80Ñ\96бна Ð°Ð²Ñ\82енÑ\82иÑ\84Ñ\96каÑ\86Ñ\96Ñ\8f, щоб установити або забрати змінні середовища з "
 "керування службами і системою."
 
-#: ../src/core/org.freedesktop.systemd1.policy.in.in.h:9
+#: src/core/org.freedesktop.systemd1.policy.in:63
 msgid "Reload the systemd state"
 msgstr "Перезапустити стан системи"
 
-#: ../src/core/org.freedesktop.systemd1.policy.in.in.h:10
+#: src/core/org.freedesktop.systemd1.policy.in:64
 msgid "Authentication is required to reload the systemd state."
-msgstr "Ð\97аÑ\81вÑ\96дÑ\87еннÑ\8f Ð¿Ð¾Ñ\82Ñ\80Ñ\96бно, щоб перезапустити стан системи."
+msgstr "Ð\9fоÑ\82Ñ\80Ñ\96бна Ð°Ð²Ñ\82енÑ\82иÑ\84Ñ\96каÑ\86Ñ\96Ñ\8f, щоб перезапустити стан системи."
 
-#: ../src/hostname/org.freedesktop.hostname1.policy.in.h:1
+#: src/hostname/org.freedesktop.hostname1.policy:22
 msgid "Set host name"
 msgstr "Встановити назву вузла"
 
-#: ../src/hostname/org.freedesktop.hostname1.policy.in.h:2
+#: src/hostname/org.freedesktop.hostname1.policy:23
 msgid "Authentication is required to set the local host name."
-msgstr "Ð\97аÑ\81вÑ\96дÑ\87еннÑ\8f Ð¿Ð¾Ñ\82Ñ\80Ñ\96бне, щоб встановити назву локального вузла."
+msgstr "Ð\9fоÑ\82Ñ\80Ñ\96бна Ð°Ð²Ñ\82енÑ\82иÑ\84Ñ\96каÑ\86Ñ\96Ñ\8f, щоб встановити назву локального вузла."
 
-#: ../src/hostname/org.freedesktop.hostname1.policy.in.h:3
+#: src/hostname/org.freedesktop.hostname1.policy:32
 msgid "Set static host name"
 msgstr "Встановити статичну назву вузла"
 
-#: ../src/hostname/org.freedesktop.hostname1.policy.in.h:4
+#: src/hostname/org.freedesktop.hostname1.policy:33
 msgid ""
 "Authentication is required to set the statically configured local host name, "
 "as well as the pretty host name."
 msgstr ""
-"Ð\97аÑ\81вÑ\96дÑ\87еннÑ\8f Ð¿Ð¾Ñ\82Ñ\80Ñ\96бне, щоб вказати статично налаштовану назву локального "
+"Ð\9fоÑ\82Ñ\80Ñ\96бна Ð°Ð²Ñ\82енÑ\82иÑ\84Ñ\96каÑ\86Ñ\96Ñ\8f, щоб вказати статично налаштовану назву локального "
 "вузла, так само й форматовану."
 
-#: ../src/hostname/org.freedesktop.hostname1.policy.in.h:5
+#: src/hostname/org.freedesktop.hostname1.policy:43
 msgid "Set machine information"
 msgstr "Встановити інформацію про машину"
 
-#: ../src/hostname/org.freedesktop.hostname1.policy.in.h:6
+#: src/hostname/org.freedesktop.hostname1.policy:44
 msgid "Authentication is required to set local machine information."
-msgstr "Ð\97аÑ\81вÑ\96дÑ\87еннÑ\8f Ð¿Ð¾Ñ\82Ñ\80Ñ\96бно, щоб вказати локальну інформацію про машини."
+msgstr "Ð\9fоÑ\82Ñ\80Ñ\96бна Ð°Ð²Ñ\82енÑ\82иÑ\84Ñ\96каÑ\86Ñ\96Ñ\8f, щоб вказати локальну інформацію про машини."
 
-#: ../src/import/org.freedesktop.import1.policy.in.h:1
+#: src/import/org.freedesktop.import1.policy:22
 msgid "Import a VM or container image"
 msgstr "Імпортувати образ контейнера або віртуальної машини"
 
-#: ../src/import/org.freedesktop.import1.policy.in.h:2
+#: src/import/org.freedesktop.import1.policy:23
 msgid "Authentication is required to import a VM or container image"
 msgstr ""
-"Ð\97аÑ\81вÑ\96дÑ\87еннÑ\8f Ð¿Ð¾Ñ\82Ñ\80Ñ\96бно, щоб імпортувати образ контейнера або віртуальної машини"
+"Ð\9fоÑ\82Ñ\80Ñ\96бна Ð°Ð²Ñ\82енÑ\82иÑ\84Ñ\96каÑ\86Ñ\96Ñ\8f, щоб імпортувати образ контейнера або віртуальної машини"
 
-#: ../src/import/org.freedesktop.import1.policy.in.h:3
+#: src/import/org.freedesktop.import1.policy:32
 msgid "Export a VM or container image"
 msgstr "Експортувати образ контейнера або віртуальної машини"
 
-#: ../src/import/org.freedesktop.import1.policy.in.h:4
+#: src/import/org.freedesktop.import1.policy:33
 msgid "Authentication is required to export a VM or container image"
 msgstr ""
-"Ð\97аÑ\81вÑ\96дÑ\87еннÑ\8f Ð¿Ð¾Ñ\82Ñ\80Ñ\96бно, щоб експортувати образ контейнера або віртуальної "
+"Ð\9fоÑ\82Ñ\80Ñ\96бна Ð°Ð²Ñ\82енÑ\82иÑ\84Ñ\96каÑ\86Ñ\96Ñ\8f, щоб експортувати образ контейнера або віртуальної "
 "машини"
 
-#: ../src/import/org.freedesktop.import1.policy.in.h:5
+#: src/import/org.freedesktop.import1.policy:42
 msgid "Download a VM or container image"
 msgstr "Звантажити образ контейнера або віртуальної машини"
 
-#: ../src/import/org.freedesktop.import1.policy.in.h:6
+#: src/import/org.freedesktop.import1.policy:43
 msgid "Authentication is required to download a VM or container image"
 msgstr ""
-"Ð\97аÑ\81вÑ\96дÑ\87еннÑ\8f Ð¿Ð¾Ñ\82Ñ\80Ñ\96бно, щоб звантажити образ контейнера або віртуальної машини"
+"Ð\9fоÑ\82Ñ\80Ñ\96бна Ð°Ð²Ñ\82енÑ\82иÑ\84Ñ\96каÑ\86Ñ\96Ñ\8f, щоб звантажити образ контейнера або віртуальної машини"
 
-#: ../src/locale/org.freedesktop.locale1.policy.in.h:1
+#: src/locale/org.freedesktop.locale1.policy:22
 msgid "Set system locale"
 msgstr "Вказати системну локаль"
 
-#: ../src/locale/org.freedesktop.locale1.policy.in.h:2
+#: src/locale/org.freedesktop.locale1.policy:23
 msgid "Authentication is required to set the system locale."
-msgstr "Ð\97аÑ\81вÑ\96дÑ\87еннÑ\8f Ð¿Ð¾Ñ\82Ñ\80Ñ\96бно, щоб встановити системну локаль."
+msgstr "Ð\9fоÑ\82Ñ\80Ñ\96бна Ð°Ð²Ñ\82енÑ\82иÑ\84Ñ\96каÑ\86Ñ\96Ñ\8f, щоб встановити системну локаль."
 
-#: ../src/locale/org.freedesktop.locale1.policy.in.h:3
+#: src/locale/org.freedesktop.locale1.policy:33
 msgid "Set system keyboard settings"
 msgstr "Вказати налаштування системної клавіатури"
 
-#: ../src/locale/org.freedesktop.locale1.policy.in.h:4
+#: src/locale/org.freedesktop.locale1.policy:34
 msgid "Authentication is required to set the system keyboard settings."
-msgstr "Ð\97аÑ\81вÑ\96дÑ\87еннÑ\8f Ð¿Ð¾Ñ\82Ñ\80Ñ\96бно, щоб вказати налаштування системної клавіатури."
+msgstr "Ð\9fоÑ\82Ñ\80Ñ\96бна Ð°Ð²Ñ\82енÑ\82иÑ\84Ñ\96каÑ\86Ñ\96Ñ\8f, щоб вказати налаштування системної клавіатури."
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:1
+#: src/login/org.freedesktop.login1.policy:22
 msgid "Allow applications to inhibit system shutdown"
 msgstr "Дозволити програмам перешкоджати вимкненню системи"
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:2
+#: src/login/org.freedesktop.login1.policy:23
 msgid ""
 "Authentication is required for an application to inhibit system shutdown."
 msgstr ""
-"Ð\97аÑ\81вÑ\96дÑ\87еннÑ\8f Ð¿Ð¾Ñ\82Ñ\80Ñ\96бно, щоб дозволити програмам перешкоджати вимкненню системи."
+"Ð\9fоÑ\82Ñ\80Ñ\96бна Ð°Ð²Ñ\82енÑ\82иÑ\84Ñ\96каÑ\86Ñ\96Ñ\8f, щоб дозволити програмам перешкоджати вимкненню системи."
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:3
+#: src/login/org.freedesktop.login1.policy:33
 msgid "Allow applications to delay system shutdown"
 msgstr "Дозволити програмам затримувати вимкнення системи"
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:4
+#: src/login/org.freedesktop.login1.policy:34
 msgid "Authentication is required for an application to delay system shutdown."
 msgstr ""
-"Ð\97аÑ\81вÑ\96дÑ\87еннÑ\8f Ð¿Ð¾Ñ\82Ñ\80Ñ\96бно, щоб дозволити програмам затримувати вимкнення системи."
+"Ð\9fоÑ\82Ñ\80Ñ\96бна Ð°Ð²Ñ\82енÑ\82иÑ\84Ñ\96каÑ\86Ñ\96Ñ\8f, щоб дозволити програмам затримувати вимкнення системи."
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:5
+#: src/login/org.freedesktop.login1.policy:44
 msgid "Allow applications to inhibit system sleep"
 msgstr "Дозволити програмам перешкоджати засинанню системи"
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:6
+#: src/login/org.freedesktop.login1.policy:45
 msgid "Authentication is required for an application to inhibit system sleep."
 msgstr ""
-"Ð\97аÑ\81вÑ\96дÑ\87еннÑ\8f Ð¿Ð¾Ñ\82Ñ\80Ñ\96бно, щоб дозволити програмам перешкоджати засинанню системи."
+"Ð\9fоÑ\82Ñ\80Ñ\96бна Ð°Ð²Ñ\82енÑ\82иÑ\84Ñ\96каÑ\86Ñ\96Ñ\8f, щоб дозволити програмам перешкоджати засинанню системи."
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:7
+#: src/login/org.freedesktop.login1.policy:55
 msgid "Allow applications to delay system sleep"
 msgstr "Дозволити програмами затримувати засинання системи"
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:8
+#: src/login/org.freedesktop.login1.policy:56
 msgid "Authentication is required for an application to delay system sleep."
 msgstr ""
-"Ð\97аÑ\81вÑ\96дÑ\87еннÑ\8f Ð¿Ð¾Ñ\82Ñ\80Ñ\96бно, щоб дозволити програмам затримувати засинання системи."
+"Ð\9fоÑ\82Ñ\80Ñ\96бна Ð°Ð²Ñ\82енÑ\82иÑ\84Ñ\96каÑ\86Ñ\96Ñ\8f, щоб дозволити програмам затримувати засинання системи."
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:9
+#: src/login/org.freedesktop.login1.policy:65
 msgid "Allow applications to inhibit automatic system suspend"
 msgstr "Дозволити програмам перешкоджати автоматичному призупиненню системи"
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:10
+#: src/login/org.freedesktop.login1.policy:66
 msgid ""
 "Authentication is required for an application to inhibit automatic system "
 "suspend."
 msgstr ""
-"Ð\97аÑ\81вÑ\96дÑ\87еннÑ\8f Ð¿Ð¾Ñ\82Ñ\80Ñ\96бно, щоб дозволити програмам перешкоджати автоматичному "
+"Ð\9fоÑ\82Ñ\80Ñ\96бна Ð°Ð²Ñ\82енÑ\82иÑ\84Ñ\96каÑ\86Ñ\96Ñ\8f, щоб дозволити програмам перешкоджати автоматичному "
 "призупиненню системи."
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:11
+#: src/login/org.freedesktop.login1.policy:75
 msgid "Allow applications to inhibit system handling of the power key"
 msgstr "Дозволити програмам перешкоджати обробленню системою клавіші живлення"
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:12
+#: src/login/org.freedesktop.login1.policy:76
 msgid ""
 "Authentication is required for an application to inhibit system handling of "
 "the power key."
 msgstr ""
-"Ð\97аÑ\81вÑ\96дÑ\87еннÑ\8f Ð¿Ð¾Ñ\82Ñ\80Ñ\96бно, щоб дозволити програмам перешкоджати обробленню "
+"Ð\9fоÑ\82Ñ\80Ñ\96бна Ð°Ð²Ñ\82енÑ\82иÑ\84Ñ\96каÑ\86Ñ\96Ñ\8f, щоб дозволити програмам перешкоджати обробленню "
 "системою клавіші живлення."
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:13
+#: src/login/org.freedesktop.login1.policy:86
 msgid "Allow applications to inhibit system handling of the suspend key"
 msgstr ""
 "Дозволити програмам перешкоджати обробленню системою клавіші призупинення"
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:14
+#: src/login/org.freedesktop.login1.policy:87
 msgid ""
 "Authentication is required for an application to inhibit system handling of "
 "the suspend key."
 msgstr ""
-"Ð\97аÑ\81вÑ\96дÑ\87еннÑ\8f Ð¿Ð¾Ñ\82Ñ\80Ñ\96бно, щоб дозволити програмам перешкоджати обробленню "
+"Ð\9fоÑ\82Ñ\80Ñ\96бна Ð°Ð²Ñ\82енÑ\82иÑ\84Ñ\96каÑ\86Ñ\96Ñ\8f, щоб дозволити програмам перешкоджати обробленню "
 "системою клавіші призупинення."
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:15
+#: src/login/org.freedesktop.login1.policy:97
 msgid "Allow applications to inhibit system handling of the hibernate key"
 msgstr ""
 "Дозволити програмам перешкоджати обробленню системою клавіші присипання"
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:16
+#: src/login/org.freedesktop.login1.policy:98
 msgid ""
 "Authentication is required for an application to inhibit system handling of "
 "the hibernate key."
 msgstr ""
-"Ð\97аÑ\81вÑ\96дÑ\87еннÑ\8f Ð¿Ð¾Ñ\82Ñ\80Ñ\96бно, щоб дозволити програмам перешкоджати обробленню "
+"Ð\9fоÑ\82Ñ\80Ñ\96бна Ð°Ð²Ñ\82енÑ\82иÑ\84Ñ\96каÑ\86Ñ\96Ñ\8f, щоб дозволити програмам перешкоджати обробленню "
 "системою клавіші присипання."
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:17
+#: src/login/org.freedesktop.login1.policy:107
 msgid "Allow applications to inhibit system handling of the lid switch"
 msgstr ""
 "Дозволити програмам перешкоджати обробленню системою клавіші перемикання "
 "кришки"
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:18
+#: src/login/org.freedesktop.login1.policy:108
 msgid ""
 "Authentication is required for an application to inhibit system handling of "
 "the lid switch."
 msgstr ""
-"Ð\97аÑ\81вÑ\96дÑ\87еннÑ\8f Ð¿Ð¾Ñ\82Ñ\80Ñ\96бно, щоб дозволити програмам перешкоджати обробленню "
+"Ð\9fоÑ\82Ñ\80Ñ\96бна Ð°Ð²Ñ\82енÑ\82иÑ\84Ñ\96каÑ\86Ñ\96Ñ\8f, щоб дозволити програмам перешкоджати обробленню "
 "системою клавіші перемикання кришки."
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:19
+#: src/login/org.freedesktop.login1.policy:117
+#| msgid "Allow non-logged-in users to run programs"
+msgid "Allow non-logged-in user to run programs"
+msgstr "Дозволити незареєстрованим користувачам запускати програми"
+
+#: src/login/org.freedesktop.login1.policy:118
+#| msgid "Authentication is required to run programs as a non-logged-in user."
+msgid "Explicit request is required to run programs as a non-logged-in user."
+msgstr ""
+"Потрібна автентифікація, щоб дозволити незареєстрованим користувачам запускати "
+"програми."
+
+#: src/login/org.freedesktop.login1.policy:127
 msgid "Allow non-logged-in users to run programs"
 msgstr "Дозволити незареєстрованим користувачам запускати програми"
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:20
+#: src/login/org.freedesktop.login1.policy:128
 msgid "Authentication is required to run programs as a non-logged-in user."
 msgstr ""
-"Ð\97аÑ\81вÑ\96дÑ\87еннÑ\8f Ð¿Ð¾Ñ\82Ñ\80Ñ\96бно, щоб дозволити незареєстрованим користувачам запускати "
+"Ð\9fоÑ\82Ñ\80Ñ\96бна Ð°Ð²Ñ\82енÑ\82иÑ\84Ñ\96каÑ\86Ñ\96Ñ\8f, щоб дозволити незареєстрованим користувачам запускати "
 "програми."
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:21
+#: src/login/org.freedesktop.login1.policy:137
 msgid "Allow attaching devices to seats"
 msgstr "Дозволити під'єднання пристроїв до місць"
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:22
+#: src/login/org.freedesktop.login1.policy:138
 msgid "Authentication is required for attaching a device to a seat."
-msgstr "Ð\97аÑ\81вÑ\96дÑ\87еннÑ\8f Ð¿Ð¾Ñ\82Ñ\80Ñ\96бно, щоб під'єднувати пристрої до місць."
+msgstr "Ð\9fоÑ\82Ñ\80Ñ\96бна Ð°Ð²Ñ\82енÑ\82иÑ\84Ñ\96каÑ\86Ñ\96Ñ\8f, щоб під'єднувати пристрої до місць."
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:23
+#: src/login/org.freedesktop.login1.policy:148
 msgid "Flush device to seat attachments"
 msgstr "Очисний пристрій для під'єднань до місця"
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:24
+#: src/login/org.freedesktop.login1.policy:149
 msgid ""
 "Authentication is required for resetting how devices are attached to seats."
-msgstr "Ð\97аÑ\81вÑ\96дÑ\87еннÑ\8f Ð¿Ð¾Ñ\82Ñ\80Ñ\96бно, щоб перезапустити спосіб під'єднання до місць."
+msgstr "Ð\9fоÑ\82Ñ\80Ñ\96бна Ð°Ð²Ñ\82енÑ\82иÑ\84Ñ\96каÑ\86Ñ\96Ñ\8f, щоб перезапустити спосіб під'єднання до місць."
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:25
+#: src/login/org.freedesktop.login1.policy:158
 msgid "Power off the system"
 msgstr "Вимкнути систему"
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:26
+#: src/login/org.freedesktop.login1.policy:159
 msgid "Authentication is required for powering off the system."
-msgstr "Ð\97аÑ\81вÑ\96дÑ\87еннÑ\8f Ð¿Ð¾Ñ\82Ñ\80Ñ\96бно, щоб вимкнути систему."
+msgstr "Ð\9fоÑ\82Ñ\80Ñ\96бна Ð°Ð²Ñ\82енÑ\82иÑ\84Ñ\96каÑ\86Ñ\96Ñ\8f, щоб вимкнути систему."
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:27
+#: src/login/org.freedesktop.login1.policy:169
 msgid "Power off the system while other users are logged in"
 msgstr "Вимкнути систему, коли інші користувачі ще в ній"
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:28
+#: src/login/org.freedesktop.login1.policy:170
 msgid ""
 "Authentication is required for powering off the system while other users are "
 "logged in."
 msgstr ""
-"Ð\97аÑ\81вÑ\96дÑ\87еннÑ\8f Ð¿Ð¾Ñ\82Ñ\80Ñ\96бно, щоб вимкнути систему, коли інші користувачі в ній."
+"Ð\9fоÑ\82Ñ\80Ñ\96бна Ð°Ð²Ñ\82енÑ\82иÑ\84Ñ\96каÑ\86Ñ\96Ñ\8f, щоб вимкнути систему, коли інші користувачі в ній."
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:29
+#: src/login/org.freedesktop.login1.policy:180
 msgid "Power off the system while an application asked to inhibit it"
 msgstr "Вимкнути систему, коли програми намагаються перешкодити цьому"
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:30
+#: src/login/org.freedesktop.login1.policy:181
 msgid ""
 "Authentication is required for powering off the system while an application "
 "asked to inhibit it."
 msgstr ""
-"Ð\97аÑ\81вÑ\96дÑ\87еннÑ\8f Ð¿Ð¾Ñ\82Ñ\80Ñ\96бно, щоб вимкнути систему, коли програми намагаються "
+"Ð\9fоÑ\82Ñ\80Ñ\96бна Ð°Ð²Ñ\82енÑ\82иÑ\84Ñ\96каÑ\86Ñ\96Ñ\8f, щоб вимкнути систему, коли програми намагаються "
 "перешкодити цьому."
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:31
+#: src/login/org.freedesktop.login1.policy:191
 msgid "Reboot the system"
 msgstr "Перезавантажити систему"
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:32
+#: src/login/org.freedesktop.login1.policy:192
 msgid "Authentication is required for rebooting the system."
 msgstr "Для перезавантаження системи необхідна ідентифікація."
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:33
+#: src/login/org.freedesktop.login1.policy:202
 msgid "Reboot the system while other users are logged in"
 msgstr "Перезавантажити, якщо інші користувачі в системі"
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:34
+#: src/login/org.freedesktop.login1.policy:203
 msgid ""
 "Authentication is required for rebooting the system while other users are "
 "logged in."
 msgstr ""
-"Ð\97аÑ\81вÑ\96дÑ\87еннÑ\8f Ð¿Ð¾Ñ\82Ñ\80Ñ\96бно, щоб перезапустити систему, коли інші користувачі в ній."
+"Ð\9fоÑ\82Ñ\80Ñ\96бна Ð°Ð²Ñ\82енÑ\82иÑ\84Ñ\96каÑ\86Ñ\96Ñ\8f, щоб перезапустити систему, коли інші користувачі в ній."
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:35
+#: src/login/org.freedesktop.login1.policy:213
 msgid "Reboot the system while an application asked to inhibit it"
 msgstr "Перезапустити систему, коли програми намагаються перешкодити цьому"
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:36
+#: src/login/org.freedesktop.login1.policy:214
 msgid ""
 "Authentication is required for rebooting the system while an application "
 "asked to inhibit it."
 msgstr ""
-"Ð\97аÑ\81вÑ\96дÑ\87еннÑ\8f Ð¿Ð¾Ñ\82Ñ\80Ñ\96бно, щоб перезапустити систему, коли програми намагаються "
+"Ð\9fоÑ\82Ñ\80Ñ\96бна Ð°Ð²Ñ\82енÑ\82иÑ\84Ñ\96каÑ\86Ñ\96Ñ\8f, щоб перезапустити систему, коли програми намагаються "
 "перешкодити цьому."
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:37
+#: src/login/org.freedesktop.login1.policy:224
+#| msgid "Hibernate the system"
+msgid "Halt the system"
+msgstr "Зупинити систему"
+
+#: src/login/org.freedesktop.login1.policy:225
+#| msgid "Authentication is required for hibernating the system."
+msgid "Authentication is required for halting the system."
+msgstr "Потрібна автентифікація, щоб зупинити систему."
+
+#: src/login/org.freedesktop.login1.policy:235
+#| msgid "Hibernate the system while other users are logged in"
+msgid "Halt the system while other users are logged in"
+msgstr "Зупинити систему, коли інші користувачі в ній"
+
+#: src/login/org.freedesktop.login1.policy:236
+#| msgid ""
+#| "Authentication is required for hibernating the system while other users "
+#| "are logged in."
+msgid ""
+"Authentication is required for halting the system while other users are "
+"logged in."
+msgstr ""
+"Потрібна автентифікація, щоб зупинити систему, коли інші користувачі в ній."
+
+#: src/login/org.freedesktop.login1.policy:246
+#| msgid "Hibernate the system while an application asked to inhibit it"
+msgid "Halt the system while an application asked to inhibit it"
+msgstr "Зупинити систему, коли програми намагаються перешкодити цьому"
+
+#: src/login/org.freedesktop.login1.policy:247
+#| msgid ""
+#| "Authentication is required for hibernating the system while an "
+#| "application asked to inhibit it."
+msgid ""
+"Authentication is required for halting the system while an application asked "
+"to inhibit it."
+msgstr ""
+"Потрібна автентифікація, щоб зупинити систему, коли програми намагаються "
+"перешкодити цьому."
+
+#: src/login/org.freedesktop.login1.policy:257
 msgid "Suspend the system"
 msgstr "Призупинити систему"
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:38
+#: src/login/org.freedesktop.login1.policy:258
 msgid "Authentication is required for suspending the system."
-msgstr "Ð\97аÑ\81вÑ\96дÑ\87еннÑ\8f Ð¿Ð¾Ñ\82Ñ\80Ñ\96бно, щоб призупинити систему."
+msgstr "Ð\9fоÑ\82Ñ\80Ñ\96бна Ð°Ð²Ñ\82енÑ\82иÑ\84Ñ\96каÑ\86Ñ\96Ñ\8f, щоб призупинити систему."
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:39
+#: src/login/org.freedesktop.login1.policy:267
 msgid "Suspend the system while other users are logged in"
 msgstr "Призупинити систему, коли інші користувачі в ній"
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:40
+#: src/login/org.freedesktop.login1.policy:268
 msgid ""
 "Authentication is required for suspending the system while other users are "
 "logged in."
 msgstr ""
-"Ð\97аÑ\81вÑ\96дÑ\87еннÑ\8f Ð¿Ð¾Ñ\82Ñ\80Ñ\96бно, щоб призупинити систему, коли інші користувачі в ній."
+"Ð\9fоÑ\82Ñ\80Ñ\96бна Ð°Ð²Ñ\82енÑ\82иÑ\84Ñ\96каÑ\86Ñ\96Ñ\8f, щоб призупинити систему, коли інші користувачі в ній."
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:41
+#: src/login/org.freedesktop.login1.policy:278
 msgid "Suspend the system while an application asked to inhibit it"
 msgstr "Призупинити систему, коли програми намагаються перешкодити цьому"
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:42
+#: src/login/org.freedesktop.login1.policy:279
 msgid ""
 "Authentication is required for suspending the system while an application "
 "asked to inhibit it."
 msgstr ""
-"Ð\97аÑ\81вÑ\96дÑ\87еннÑ\8f Ð¿Ð¾Ñ\82Ñ\80Ñ\96бно, щоб призупинити систему, коли програми намагаються "
+"Ð\9fоÑ\82Ñ\80Ñ\96бна Ð°Ð²Ñ\82енÑ\82иÑ\84Ñ\96каÑ\86Ñ\96Ñ\8f, щоб призупинити систему, коли програми намагаються "
 "перешкодити цьому."
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:43
+#: src/login/org.freedesktop.login1.policy:289
 msgid "Hibernate the system"
 msgstr "Приспати систему"
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:44
+#: src/login/org.freedesktop.login1.policy:290
 msgid "Authentication is required for hibernating the system."
-msgstr "Ð\97аÑ\81вÑ\96дÑ\87еннÑ\8f Ð¿Ð¾Ñ\82Ñ\80Ñ\96бно, щоб приспати систему."
+msgstr "Ð\9fоÑ\82Ñ\80Ñ\96бна Ð°Ð²Ñ\82енÑ\82иÑ\84Ñ\96каÑ\86Ñ\96Ñ\8f, щоб приспати систему."
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:45
+#: src/login/org.freedesktop.login1.policy:299
 msgid "Hibernate the system while other users are logged in"
 msgstr "Приспати систему, коли інші користувачі в ній"
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:46
+#: src/login/org.freedesktop.login1.policy:300
 msgid ""
 "Authentication is required for hibernating the system while other users are "
 "logged in."
 msgstr ""
-"Ð\97аÑ\81вÑ\96дÑ\87еннÑ\8f Ð¿Ð¾Ñ\82Ñ\80Ñ\96бно, щоб присипання систему, коли інші користувачі в ній."
+"Ð\9fоÑ\82Ñ\80Ñ\96бна Ð°Ð²Ñ\82енÑ\82иÑ\84Ñ\96каÑ\86Ñ\96Ñ\8f, щоб присипання систему, коли інші користувачі в ній."
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:47
+#: src/login/org.freedesktop.login1.policy:310
 msgid "Hibernate the system while an application asked to inhibit it"
 msgstr "Приспати систему, коли програми намагаються перешкодити цьому"
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:48
+#: src/login/org.freedesktop.login1.policy:311
 msgid ""
 "Authentication is required for hibernating the system while an application "
 "asked to inhibit it."
 msgstr ""
-"Ð\97аÑ\81вÑ\96дÑ\87еннÑ\8f Ð¿Ð¾Ñ\82Ñ\80Ñ\96бно, щоб приспати систему, коли програми намагаються "
+"Ð\9fоÑ\82Ñ\80Ñ\96бна Ð°Ð²Ñ\82енÑ\82иÑ\84Ñ\96каÑ\86Ñ\96Ñ\8f, щоб приспати систему, коли програми намагаються "
 "перешкодити цьому."
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:49
+#: src/login/org.freedesktop.login1.policy:321
 msgid "Manage active sessions, users and seats"
 msgstr "Керувати сеансами, користувачами і робочими місцями"
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:50
+#: src/login/org.freedesktop.login1.policy:322
 msgid ""
 "Authentication is required for managing active sessions, users and seats."
 msgstr ""
-"Ð\97аÑ\81вÑ\96дÑ\87еннÑ\8f Ð¿Ð¾Ñ\82Ñ\80Ñ\96бно, щоб керувати сеансами, користувачами і робочими "
+"Ð\9fоÑ\82Ñ\80Ñ\96бна Ð°Ð²Ñ\82енÑ\82иÑ\84Ñ\96каÑ\86Ñ\96Ñ\8f, щоб керувати сеансами, користувачами і робочими "
 "місцями."
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:51
+#: src/login/org.freedesktop.login1.policy:331
 msgid "Lock or unlock active sessions"
 msgstr "Заблокувати або розблокувати сеанси"
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:52
+#: src/login/org.freedesktop.login1.policy:332
 msgid "Authentication is required to lock or unlock active sessions."
-msgstr "Ð\97аÑ\81вÑ\96дÑ\87еннÑ\8f Ð¿Ð¾Ñ\82Ñ\80Ñ\96бно, щоб заблокувати або розблокувати сеанси."
+msgstr "Ð\9fоÑ\82Ñ\80Ñ\96бна Ð°Ð²Ñ\82енÑ\82иÑ\84Ñ\96каÑ\86Ñ\96Ñ\8f, щоб заблокувати або розблокувати сеанси."
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:53
+#: src/login/org.freedesktop.login1.policy:341
 msgid "Allow indication to the firmware to boot to setup interface"
 msgstr "Дозволити мікрокоду визначати, чи завантажувати інтерфейс встановлення"
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:54
+#: src/login/org.freedesktop.login1.policy:342
 msgid ""
 "Authentication is required to indicate to the firmware to boot to setup "
 "interface."
 msgstr ""
-"Ð\97аÑ\81вÑ\96дÑ\87еннÑ\8f Ð¿Ð¾Ñ\82Ñ\80Ñ\96бне, щоб дозволити мікрокоду визначати, чи завантажувати "
+"Ð\9fоÑ\82Ñ\80Ñ\96бна Ð°Ð²Ñ\82енÑ\82иÑ\84Ñ\96каÑ\86Ñ\96Ñ\8f, щоб дозволити мікрокоду визначати, чи завантажувати "
 "інтерфейс встановлення."
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:55
+#: src/login/org.freedesktop.login1.policy:351
 msgid "Set a wall message"
 msgstr "Вказати повідомлення на стіні"
 
-#: ../src/login/org.freedesktop.login1.policy.in.h:56
+#: src/login/org.freedesktop.login1.policy:352
 msgid "Authentication is required to set a wall message"
-msgstr "Ð\97аÑ\81вÑ\96дÑ\87еннÑ\8f Ð¿Ð¾Ñ\82Ñ\80Ñ\96бне, щоб вказати повідомлення на стіні"
+msgstr "Ð\9fоÑ\82Ñ\80Ñ\96бна Ð°Ð²Ñ\82енÑ\82иÑ\84Ñ\96каÑ\86Ñ\96Ñ\8f, щоб вказати повідомлення на стіні"
 
-#: ../src/machine/org.freedesktop.machine1.policy.in.h:1
+#: src/machine/org.freedesktop.machine1.policy:22
 msgid "Log into a local container"
 msgstr "Увійти в локальний контейнер"
 
-#: ../src/machine/org.freedesktop.machine1.policy.in.h:2
+#: src/machine/org.freedesktop.machine1.policy:23
 msgid "Authentication is required to log into a local container."
-msgstr "Ð\97аÑ\81вÑ\96дÑ\87еннÑ\8f Ð¿Ð¾Ñ\82Ñ\80Ñ\96бне, щоб увійти в локальний контейнер."
+msgstr "Ð\9fоÑ\82Ñ\80Ñ\96бна Ð°Ð²Ñ\82енÑ\82иÑ\84Ñ\96каÑ\86Ñ\96Ñ\8f, щоб увійти в локальний контейнер."
 
-#: ../src/machine/org.freedesktop.machine1.policy.in.h:3
+#: src/machine/org.freedesktop.machine1.policy:32
 msgid "Log into the local host"
 msgstr "Увійти в локальний вузол"
 
-#: ../src/machine/org.freedesktop.machine1.policy.in.h:4
+#: src/machine/org.freedesktop.machine1.policy:33
 msgid "Authentication is required to log into the local host."
-msgstr "Ð\97аÑ\81вÑ\96дÑ\87еннÑ\8f Ð¿Ð¾Ñ\82Ñ\80Ñ\96бне, щоб увійти в локальний вузол."
+msgstr "Ð\9fоÑ\82Ñ\80Ñ\96бна Ð°Ð²Ñ\82енÑ\82иÑ\84Ñ\96каÑ\86Ñ\96Ñ\8f, щоб увійти в локальний вузол."
 
-#: ../src/machine/org.freedesktop.machine1.policy.in.h:5
+#: src/machine/org.freedesktop.machine1.policy:42
 msgid "Acquire a shell in a local container"
 msgstr "Перейняти оболонку в локальному контейнері"
 
-#: ../src/machine/org.freedesktop.machine1.policy.in.h:6
+#: src/machine/org.freedesktop.machine1.policy:43
 msgid "Authentication is required to acquire a shell in a local container."
-msgstr "Ð\97аÑ\81вÑ\96дÑ\87еннÑ\8f Ð¿Ð¾Ñ\82Ñ\80Ñ\96бне, щоб перейняти оболонку в локальному контейнері."
+msgstr "Ð\9fоÑ\82Ñ\80Ñ\96бна Ð°Ð²Ñ\82енÑ\82иÑ\84Ñ\96каÑ\86Ñ\96Ñ\8f, щоб перейняти оболонку в локальному контейнері."
 
-#: ../src/machine/org.freedesktop.machine1.policy.in.h:7
+#: src/machine/org.freedesktop.machine1.policy:53
 msgid "Acquire a shell on the local host"
 msgstr "Перейняти оболонку на локальному вузлі"
 
-#: ../src/machine/org.freedesktop.machine1.policy.in.h:8
+#: src/machine/org.freedesktop.machine1.policy:54
 msgid "Authentication is required to acquire a shell on the local host."
-msgstr "Ð\97аÑ\81вÑ\96дÑ\87еннÑ\8f Ð¿Ð¾Ñ\82Ñ\80Ñ\96бне, щоб перейняти оболонку на локальному вузлі."
+msgstr "Ð\9fоÑ\82Ñ\80Ñ\96бна Ð°Ð²Ñ\82енÑ\82иÑ\84Ñ\96каÑ\86Ñ\96Ñ\8f, щоб перейняти оболонку на локальному вузлі."
 
-#: ../src/machine/org.freedesktop.machine1.policy.in.h:9
+#: src/machine/org.freedesktop.machine1.policy:64
 msgid "Acquire a pseudo TTY in a local container"
 msgstr "Перейняти псевдо TTY в локальному контейнері"
 
-#: ../src/machine/org.freedesktop.machine1.policy.in.h:10
+#: src/machine/org.freedesktop.machine1.policy:65
 msgid ""
 "Authentication is required to acquire a pseudo TTY in a local container."
-msgstr "Засвідчення потрібне, щоб перейняти псевдо TTY в локальному контейнері."
+msgstr ""
+"Потрібна автентифікація, щоб перейняти псевдо TTY в локальному контейнері."
 
-#: ../src/machine/org.freedesktop.machine1.policy.in.h:11
+#: src/machine/org.freedesktop.machine1.policy:74
 msgid "Acquire a pseudo TTY on the local host"
 msgstr "Перейняти псевдо TTY на локальному вузлі"
 
-#: ../src/machine/org.freedesktop.machine1.policy.in.h:12
+#: src/machine/org.freedesktop.machine1.policy:75
 msgid "Authentication is required to acquire a pseudo TTY on the local host."
-msgstr "Ð\97аÑ\81вÑ\96дÑ\87еннÑ\8f Ð¿Ð¾Ñ\82Ñ\80Ñ\96бне, щоб перейняти псевдо TTY на локальному вузлі."
+msgstr "Ð\9fоÑ\82Ñ\80Ñ\96бна Ð°Ð²Ñ\82енÑ\82иÑ\84Ñ\96каÑ\86Ñ\96Ñ\8f, щоб перейняти псевдо TTY на локальному вузлі."
 
-#: ../src/machine/org.freedesktop.machine1.policy.in.h:13
+#: src/machine/org.freedesktop.machine1.policy:84
 msgid "Manage local virtual machines and containers"
 msgstr "Керувати локальними віртуальними машинами і контейнерами"
 
-#: ../src/machine/org.freedesktop.machine1.policy.in.h:14
+#: src/machine/org.freedesktop.machine1.policy:85
 msgid ""
 "Authentication is required to manage local virtual machines and containers."
 msgstr ""
-"Ð\97аÑ\81вÑ\96дÑ\87еннÑ\8f Ð¿Ð¾Ñ\82Ñ\80Ñ\96бно, щоб керувати локальними віртуальними машинами і "
+"Ð\9fоÑ\82Ñ\80Ñ\96бна Ð°Ð²Ñ\82енÑ\82иÑ\84Ñ\96каÑ\86Ñ\96Ñ\8f, щоб керувати локальними віртуальними машинами і "
 "контейнерами."
 
-#: ../src/machine/org.freedesktop.machine1.policy.in.h:15
+#: src/machine/org.freedesktop.machine1.policy:95
 msgid "Manage local virtual machine and container images"
 msgstr "Керувати локальними образами віртуальних машин і контейнерів"
 
-#: ../src/machine/org.freedesktop.machine1.policy.in.h:16
+#: src/machine/org.freedesktop.machine1.policy:96
 msgid ""
 "Authentication is required to manage local virtual machine and container "
 "images."
 msgstr ""
-"Ð\97аÑ\81вÑ\96дÑ\87еннÑ\8f Ð¿Ð¾Ñ\82Ñ\80Ñ\96бно, щоб керувати локальними образами віртуальних машин і "
+"Ð\9fоÑ\82Ñ\80Ñ\96бна Ð°Ð²Ñ\82енÑ\82иÑ\84Ñ\96каÑ\86Ñ\96Ñ\8f, щоб керувати локальними образами віртуальних машин і "
 "контейнерів."
 
-#: ../src/timedate/org.freedesktop.timedate1.policy.in.h:1
+#: src/resolve/org.freedesktop.resolve1.policy:22
+msgid "Register a DNS-SD service"
+msgstr "Зареєструвати службу DNS-SD"
+
+#: src/resolve/org.freedesktop.resolve1.policy:23
+#| msgid "Authentication is required to set a wall message"
+msgid "Authentication is required to register a DNS-SD service"
+msgstr "Потрібна автентифікація, щоб зареєструвати службу DNS-SD"
+
+#: src/resolve/org.freedesktop.resolve1.policy:33
+msgid "Unregister a DNS-SD service"
+msgstr "Зняти з реєстрації службу DNS-SD"
+
+#: src/resolve/org.freedesktop.resolve1.policy:34
+#| msgid "Authentication is required to set a wall message"
+msgid "Authentication is required to unregister a DNS-SD service"
+msgstr "Потрібна автентифікація, щоб зняти з реєстрації службу DNS-SD"
+
+#: src/timedate/org.freedesktop.timedate1.policy:22
 msgid "Set system time"
 msgstr "Вказати системний час"
 
-#: ../src/timedate/org.freedesktop.timedate1.policy.in.h:2
+#: src/timedate/org.freedesktop.timedate1.policy:23
 msgid "Authentication is required to set the system time."
-msgstr "Ð\97аÑ\81вÑ\96дÑ\87еннÑ\8f Ð¿Ð¾Ñ\82Ñ\80Ñ\96бно, щоб вказати системний час."
+msgstr "Ð\9fоÑ\82Ñ\80Ñ\96бна Ð°Ð²Ñ\82енÑ\82иÑ\84Ñ\96каÑ\86Ñ\96Ñ\8f, щоб вказати системний час."
 
-#: ../src/timedate/org.freedesktop.timedate1.policy.in.h:3
+#: src/timedate/org.freedesktop.timedate1.policy:33
 msgid "Set system timezone"
 msgstr "Вказати системний часовий пояс"
 
-#: ../src/timedate/org.freedesktop.timedate1.policy.in.h:4
+#: src/timedate/org.freedesktop.timedate1.policy:34
 msgid "Authentication is required to set the system timezone."
-msgstr "Ð\97аÑ\81вÑ\96дÑ\87еннÑ\8f Ð¿Ð¾Ñ\82Ñ\80Ñ\96бно, щоб вказати системний часовий пояс."
+msgstr "Ð\9fоÑ\82Ñ\80Ñ\96бна Ð°Ð²Ñ\82енÑ\82иÑ\84Ñ\96каÑ\86Ñ\96Ñ\8f, щоб вказати системний часовий пояс."
 
-#: ../src/timedate/org.freedesktop.timedate1.policy.in.h:5
+#: src/timedate/org.freedesktop.timedate1.policy:43
 msgid "Set RTC to local timezone or UTC"
 msgstr "Вкажіть RTC для локального часового поясу або UTC"
 
-#: ../src/timedate/org.freedesktop.timedate1.policy.in.h:6
+#: src/timedate/org.freedesktop.timedate1.policy:44
 msgid ""
 "Authentication is required to control whether the RTC stores the local or "
 "UTC time."
-msgstr "Ð\97аÑ\81вÑ\96дÑ\87еннÑ\8f Ð¿Ð¾Ñ\82Ñ\80Ñ\96бно, щоб контролювати, чи RTC зберігає час, чи UTC."
+msgstr "Ð\9fоÑ\82Ñ\80Ñ\96бна Ð°Ð²Ñ\82енÑ\82иÑ\84Ñ\96каÑ\86Ñ\96Ñ\8f, щоб контролювати, чи RTC зберігає час, чи UTC."
 
-#: ../src/timedate/org.freedesktop.timedate1.policy.in.h:7
+#: src/timedate/org.freedesktop.timedate1.policy:54
 msgid "Turn network time synchronization on or off"
-msgstr "Увімкнути або вимкнути синхронізування через мережу"
+msgstr "УвÑ\96мкнÑ\83Ñ\82и Ð°Ð±Ð¾ Ð²Ð¸Ð¼ÐºÐ½Ñ\83Ñ\82и Ñ\81инÑ\85Ñ\80онÑ\96зÑ\83ваннÑ\8f Ñ\87аÑ\81Ñ\83 Ñ\87еÑ\80ез Ð¼ÐµÑ\80ежÑ\83"
 
-#: ../src/timedate/org.freedesktop.timedate1.policy.in.h:8
+#: src/timedate/org.freedesktop.timedate1.policy:55
 msgid ""
 "Authentication is required to control whether network time synchronization "
 "shall be enabled."
 msgstr ""
-"Ð\97аÑ\81вÑ\96дÑ\87еннÑ\8f Ð¿Ð¾Ñ\82Ñ\80Ñ\96бно, щоб контролювати, чи синхронізування часу через мережу "
+"Ð\9fоÑ\82Ñ\80Ñ\96бна Ð°Ð²Ñ\82енÑ\82иÑ\84Ñ\96каÑ\86Ñ\96Ñ\8f, щоб контролювати, чи синхронізування часу через мережу "
 "запущено."
 
-#: ../src/core/dbus-unit.c:449
+#: src/core/dbus-unit.c:496
 msgid "Authentication is required to start '$(unit)'."
-msgstr "Ð\97аÑ\81вÑ\96дÑ\87еннÑ\8f Ð¿Ð¾Ñ\82Ñ\80Ñ\96бно, щоб запустити «$(unit)»."
+msgstr "Ð\9fоÑ\82Ñ\80Ñ\96бна Ð°Ð²Ñ\82енÑ\82иÑ\84Ñ\96каÑ\86Ñ\96Ñ\8f, щоб запустити «$(unit)»."
 
-#: ../src/core/dbus-unit.c:450
+#: src/core/dbus-unit.c:497
 msgid "Authentication is required to stop '$(unit)'."
-msgstr "Ð\97аÑ\81вÑ\96дÑ\87еннÑ\8f Ð¿Ð¾Ñ\82Ñ\80Ñ\96бно, щоб зупинити «$(unit)»."
+msgstr "Ð\9fоÑ\82Ñ\80Ñ\96бна Ð°Ð²Ñ\82енÑ\82иÑ\84Ñ\96каÑ\86Ñ\96Ñ\8f, щоб зупинити «$(unit)»."
 
-#: ../src/core/dbus-unit.c:451
+#: src/core/dbus-unit.c:498
 msgid "Authentication is required to reload '$(unit)'."
-msgstr "Ð\97аÑ\81вÑ\96дÑ\87еннÑ\8f Ð¿Ð¾Ñ\82Ñ\80Ñ\96бно, щоб перезавантажити «$(unit)»."
+msgstr "Ð\9fоÑ\82Ñ\80Ñ\96бна Ð°Ð²Ñ\82енÑ\82иÑ\84Ñ\96каÑ\86Ñ\96Ñ\8f, щоб перезавантажити «$(unit)»."
 
-#: ../src/core/dbus-unit.c:452 ../src/core/dbus-unit.c:453
+#: src/core/dbus-unit.c:499 src/core/dbus-unit.c:500
 msgid "Authentication is required to restart '$(unit)'."
-msgstr "Ð\97аÑ\81вÑ\96дÑ\87еннÑ\8f Ð¿Ð¾Ñ\82Ñ\80Ñ\96бно, щоб перезапустити «$(unit)»."
+msgstr "Ð\9fоÑ\82Ñ\80Ñ\96бна Ð°Ð²Ñ\82енÑ\82иÑ\84Ñ\96каÑ\86Ñ\96Ñ\8f, щоб перезапустити «$(unit)»."
 
-#: ../src/core/dbus-unit.c:556
+#: src/core/dbus-unit.c:607
 msgid "Authentication is required to kill '$(unit)'."
-msgstr "Ð\97аÑ\81вÑ\96дÑ\87еннÑ\8f Ð¿Ð¾Ñ\82Ñ\80Ñ\96бне, щоб вбити «$(unit)»."
+msgstr "Ð\9fоÑ\82Ñ\80Ñ\96бна Ð°Ð²Ñ\82енÑ\82иÑ\84Ñ\96каÑ\86Ñ\96Ñ\8f, щоб вбити «$(unit)»."
 
-#: ../src/core/dbus-unit.c:586
+#: src/core/dbus-unit.c:638
 msgid "Authentication is required to reset the \"failed\" state of '$(unit)'."
-msgstr "Ð\97аÑ\81вÑ\96дÑ\87еннÑ\8f Ð¿Ð¾Ñ\82Ñ\80Ñ\96бне, щоб скинути «пошкоджений» стан з «$(unit)»."
+msgstr "Ð\9fоÑ\82Ñ\80Ñ\96бна Ð°Ð²Ñ\82енÑ\82иÑ\84Ñ\96каÑ\86Ñ\96Ñ\8f, щоб скинути «пошкоджений» стан з «$(unit)»."
 
-#: ../src/core/dbus-unit.c:618
+#: src/core/dbus-unit.c:671
 msgid "Authentication is required to set properties on '$(unit)'."
-msgstr "Ð\97аÑ\81вÑ\96дÑ\87еннÑ\8f Ð¿Ð¾Ñ\82Ñ\80Ñ\96бно, щоб вказати властивості на «$(unit)»."
+msgstr "Ð\9fоÑ\82Ñ\80Ñ\96бна Ð°Ð²Ñ\82енÑ\82иÑ\84Ñ\96каÑ\86Ñ\96Ñ\8f, щоб вказати властивості на «$(unit)»."
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 c357c25bc32d87b1f80eac36eb3085e5c26d34ce..1ac8ac7ecae1785616aac5e5cf3eef851585137c 100644 (file)
@@ -28,20 +28,23 @@ __contains_word () {
 
 __get_machines() {
         local a b
-        machinectl list --no-legend --no-pager | { while read a b; do echo " $a"; done; };
+        machinectl list --no-legend --no-pager 2>/dev/null |
+                { while read a b; do echo " $a"; done; };
 }
 
 __get_busnames() {
         local mode=$1
         local a b
-        busctl $mode list --no-legend --no-pager | { while read a b; do echo " $a"; done; };
+        busctl $mode list --no-legend --no-pager 2>/dev/null |
+                { while read a b; do echo " $a"; done; };
 }
 
 __get_objects() {
         local mode=$1
         local busname=$2
         local a b
-        busctl $mode tree --list --no-legend --no-pager $busname | { while read a b; do echo " $a"; done; };
+        busctl $mode tree --list --no-legend --no-pager $busname 2>/dev/null |
+                { while read a b; do echo " $a"; done; };
 }
 
 __get_interfaces() {
@@ -49,7 +52,8 @@ __get_interfaces() {
         local busname=$2
         local path=$3
         local a b c
-        busctl $mode introspect --list --no-legend --no-pager $busname $path | { while read a b c; do [[ "$b" == "interface" ]] && echo " $a"; done; };
+        busctl $mode introspect --list --no-legend --no-pager $busname $path 2>/dev/null |
+                { while read a b c; do [[ "$b" == "interface" ]] && echo " $a"; done; };
 }
 
 __get_members() {
@@ -60,7 +64,9 @@ __get_members() {
         local type=$5
         local flags=$6
         local a b c d e
-        busctl $mode introspect --list --no-legend --no-pager $busname $path $interface | sed -e 's/^\.//' | { while read a b c d e; do [[ "$b" == "$type" && ( -z $flags || "$e" == "$flags" ) ]] && echo " $a"; done; };
+        busctl $mode introspect --list --no-legend --no-pager $busname $path $interface 2>/dev/null |
+                sed -e 's/^\.//' |
+                { while read a b c d e; do [[ "$b" == "$type" && ( -z $flags || "$e" == "$flags" ) ]] && echo " $a"; done; };
 }
 
 __get_signature() {
@@ -70,7 +76,8 @@ __get_signature() {
         local interface=$4
         local member=$5
         local a b c d
-        busctl $mode introspect --list --no-legend --no-pager $busname $path $interface | sed -e 's/^\.//' | { while read a b c d; do [[ "$a" == "$member" && "$c" != '-' ]] && echo " \"$c\""; done; };
+        busctl $mode introspect --list --no-legend --no-pager $busname $path $interface 2>/dev/null |
+                sed -e 's/^\.//' | { while read a b c d; do [[ "$a" == "$member" && "$c" != '-' ]] && echo " \"$c\""; done; };
 }
 
 _busctl() {
index a66ddccb020f4be65f165dd688a99c4208dff225..1d46a3c91460956e69d2559de611aaaf02fbb893 100644 (file)
@@ -38,7 +38,7 @@ _systemd_analyze() {
         local -A OPTS=(
                [STANDALONE]='-h --help --version --system --user --global --order --require --no-pager
                              --man=no --generators=yes'
-                      [ARG]='-H --host -M --machine --fuzz --from-pattern --to-pattern'
+                      [ARG]='-H --host -M --machine --fuzz --from-pattern --to-pattern --root'
         )
 
         local -A VERBS=(
@@ -50,8 +50,15 @@ _systemd_analyze() {
                 [VERIFY]='verify'
                 [SECCOMP_FILTER]='syscall-filter'
                 [SERVICE_WATCHDOGS]='service-watchdogs'
+                [CAT_CONFIG]='cat-config'
         )
 
+        local CONFIGS='systemd/bootchart.conf systemd/coredump.conf systemd/journald.conf
+                       systemd/journal-remote.conf systemd/journal-upload.conf systemd/logind.conf
+                       systemd/resolved.conf systemd/networkd.conf systemd/resolved.conf
+                       systemd/sleep.conf systemd/system.conf systemd/timedated.conf
+                       systemd/timesyncd.conf systemd/user.conf udev/udev.conf'
+
         _init_completion || return
 
         for ((i=0; i < COMP_CWORD; i++)); do
@@ -85,12 +92,12 @@ _systemd_analyze() {
 
         elif __contains_word "$verb" ${VERBS[STANDALONE]}; then
                 if [[ $cur = -* ]]; then
-                        comps='--help --version --system --user --global'
+                        comps='--help --version --system --user --global --no-pager'
                 fi
 
         elif __contains_word "$verb" ${VERBS[CRITICAL_CHAIN]}; then
                 if [[ $cur = -* ]]; then
-                        comps='--help --version --system --user --fuzz'
+                        comps='--help --version --system --user --fuzz --no-pager'
                 fi
 
         elif __contains_word "$verb" ${VERBS[DOT]}; then
@@ -114,7 +121,7 @@ _systemd_analyze() {
 
         elif __contains_word "$verb" ${VERBS[SECCOMP_FILTER]}; then
                 if [[ $cur = -* ]]; then
-                        comps='--help --version'
+                        comps='--help --version --no-pager'
                 fi
 
         elif __contains_word "$verb" ${VERBS[VERIFY]}; then
@@ -132,6 +139,16 @@ _systemd_analyze() {
                         comps='on off'
                 fi
 
+        elif __contains_word "$verb" ${VERBS[CAT_CONFIG]}; then
+                if [[ $cur = -* ]]; then
+                        comps='--help --version --root --no-pager'
+                elif [[ -z $cur ]]; then
+                        comps="$CONFIGS"
+                        compopt -o filenames
+                else
+                        comps="$CONFIGS $( compgen -A file -- "$cur" )"
+                        compopt -o filenames
+                fi
         fi
 
         COMPREPLY=( $(compgen -W '$comps' -- "$cur") )
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 06add1171de23937554c587fe1c1ae9b2c0d35f6..580bc30e1210c6d5f04a1a0df94f644d8a00489b 100644 (file)
 #include "bus-unit-util.h"
 #include "bus-util.h"
 #include "calendarspec.h"
+#include "def.h"
+#include "conf-files.h"
+#include "copy.h"
+#include "fd-util.h"
 #include "glob-util.h"
 #include "hashmap.h"
 #include "locale-util.h"
 #include "log.h"
 #include "pager.h"
 #include "parse-util.h"
+#include "path-util.h"
 #if HAVE_SECCOMP
 #include "seccomp-util.h"
 #endif
@@ -70,6 +75,7 @@ static const char *arg_host = NULL;
 static UnitFileScope arg_scope = UNIT_FILE_SYSTEM;
 static bool arg_man = true;
 static bool arg_generators = false;
+static const char *arg_root = NULL;
 
 struct boot_times {
         usec_t firmware_time;
@@ -118,23 +124,19 @@ struct host_info {
         char *architecture;
 };
 
-static int acquire_systemd_bus(sd_bus **bus) {
-        bool user = arg_scope != UNIT_FILE_SYSTEM;
-
-        return bus_connect_transport_systemd(arg_transport, arg_host, user, bus);
-}
-
-static int acquire_full_bus(bool *use_full_bus, sd_bus **bus) {
+static int acquire_bus(sd_bus **bus, bool *use_full_bus) {
         bool user = arg_scope != UNIT_FILE_SYSTEM;
+        int r;
 
-        if (*use_full_bus) {
-                if (bus_connect_transport(arg_transport, arg_host, user, bus) == 0)
-                        return 0;
+        if (use_full_bus && *use_full_bus) {
+                r = bus_connect_transport(arg_transport, arg_host, user, bus);
+                if (IN_SET(r, 0, -EHOSTDOWN))
+                        return r;
 
                 *use_full_bus = false;
         }
 
-        return acquire_systemd_bus(bus);
+        return bus_connect_transport_systemd(arg_transport, arg_host, user, bus);
 }
 
 static int bus_get_uint64_property(sd_bus *bus, const char *path, const char *interface, const char *property, uint64_t *val) {
@@ -606,7 +608,7 @@ static int analyze_plot(int argc, char *argv[], void *userdata) {
         _cleanup_free_ char *pretty_times = NULL;
         struct unit_times *u;
 
-        r = acquire_full_bus(&use_full_bus, &bus);
+        r = acquire_bus(&bus, &use_full_bus);
         if (r < 0)
                 return log_error_errno(r, "Failed to create bus connection: %m");
 
@@ -1015,7 +1017,7 @@ static int analyze_critical_chain(int argc, char *argv[], void *userdata) {
         Hashmap *h;
         int n, r;
 
-        r = acquire_systemd_bus(&bus);
+        r = acquire_bus(&bus, NULL);
         if (r < 0)
                 return log_error_errno(r, "Failed to create bus connection: %m");
 
@@ -1057,7 +1059,7 @@ static int analyze_blame(int argc, char *argv[], void *userdata) {
         unsigned i;
         int n, r;
 
-        r = acquire_systemd_bus(&bus);
+        r = acquire_bus(&bus, NULL);
         if (r < 0)
                 return log_error_errno(r, "Failed to create bus connection: %m");
 
@@ -1085,7 +1087,7 @@ static int analyze_time(int argc, char *argv[], void *userdata) {
         _cleanup_free_ char *buf = NULL;
         int r;
 
-        r = acquire_systemd_bus(&bus);
+        r = acquire_bus(&bus, NULL);
         if (r < 0)
                 return log_error_errno(r, "Failed to create bus connection: %m");
 
@@ -1219,7 +1221,7 @@ static int dot(int argc, char *argv[], void *userdata) {
         int r;
         UnitInfo u;
 
-        r = acquire_systemd_bus(&bus);
+        r = acquire_bus(&bus, NULL);
         if (r < 0)
                 return log_error_errno(r, "Failed to create bus connection: %m");
 
@@ -1279,36 +1281,108 @@ static int dot(int argc, char *argv[], void *userdata) {
         return 0;
 }
 
+static int dump_fallback(sd_bus *bus) {
+        _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
+        _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
+        const char *text = NULL;
+        int r;
+
+        assert(bus);
+
+        r = sd_bus_call_method(
+                        bus,
+                        "org.freedesktop.systemd1",
+                        "/org/freedesktop/systemd1",
+                        "org.freedesktop.systemd1.Manager",
+                        "Dump",
+                        &error,
+                        &reply,
+                        NULL);
+        if (r < 0)
+                return log_error_errno(r, "Failed to issue method call Dump: %s", bus_error_message(&error, r));
+
+        r = sd_bus_message_read(reply, "s", &text);
+        if (r < 0)
+                return bus_log_parse_error(r);
+
+        fputs(text, stdout);
+        return 0;
+}
+
 static int dump(int argc, char *argv[], void *userdata) {
         _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
         _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
         _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
-        const char *text = NULL;
+        int fd = -1;
         int r;
 
-        r = acquire_systemd_bus(&bus);
+        r = acquire_bus(&bus, NULL);
         if (r < 0)
                 return log_error_errno(r, "Failed to create bus connection: %m");
 
         (void) pager_open(arg_no_pager, false);
 
+        if (!sd_bus_can_send(bus, SD_BUS_TYPE_UNIX_FD))
+                return dump_fallback(bus);
+
         r = sd_bus_call_method(
                         bus,
                         "org.freedesktop.systemd1",
                         "/org/freedesktop/systemd1",
                         "org.freedesktop.systemd1.Manager",
-                        "Dump",
+                        "DumpByFileDescriptor",
                         &error,
                         &reply,
                         NULL);
-        if (r < 0)
-                return log_error_errno(r, "Failed to issue method call: %s", bus_error_message(&error, r));
+        if (r < 0) {
+                /* fall back to Dump if DumpByFileDescriptor is not supported */
+                if (!IN_SET(r, -EACCES, -EBADR))
+                        return log_error_errno(r, "Failed to issue method call DumpByFileDescriptor: %s", bus_error_message(&error, r));
 
-        r = sd_bus_message_read(reply, "s", &text);
+                return dump_fallback(bus);
+        }
+
+        r = sd_bus_message_read(reply, "h", &fd);
         if (r < 0)
                 return bus_log_parse_error(r);
 
-        fputs(text, stdout);
+        fflush(stdout);
+        return copy_bytes(fd, STDOUT_FILENO, (uint64_t) -1, 0);
+}
+
+static int cat_config(int argc, char *argv[], void *userdata) {
+        char **arg;
+        int r;
+
+        (void) pager_open(arg_no_pager, false);
+
+        STRV_FOREACH(arg, argv + 1) {
+                const char *t = NULL;
+
+                if (arg != argv + 1)
+                        print_separator();
+
+                if (path_is_absolute(*arg)) {
+                        const char *dir;
+
+                        NULSTR_FOREACH(dir, CONF_PATHS_NULSTR("")) {
+                                t = path_startswith(*arg, dir);
+                                if (t)
+                                        break;
+                        }
+
+                        if (!t) {
+                                log_error("Path %s does not start with any known prefix.", *arg);
+                                return -EINVAL;
+                        }
+                } else
+                        t = *arg;
+
+                r = conf_files_cat(arg_root, t);
+                if (r < 0)
+                        return r;
+        }
+
         return 0;
 }
 
@@ -1320,7 +1394,7 @@ static int set_log_level(int argc, char *argv[], void *userdata) {
         assert(argc == 2);
         assert(argv);
 
-        r = acquire_systemd_bus(&bus);
+        r = acquire_bus(&bus, NULL);
         if (r < 0)
                 return log_error_errno(r, "Failed to create bus connection: %m");
 
@@ -1345,7 +1419,7 @@ static int get_log_level(int argc, char *argv[], void *userdata) {
         _cleanup_free_ char *level = NULL;
         int r;
 
-        r = acquire_systemd_bus(&bus);
+        r = acquire_bus(&bus, NULL);
         if (r < 0)
                 return log_error_errno(r, "Failed to create bus connection: %m");
 
@@ -1376,7 +1450,7 @@ static int set_log_target(int argc, char *argv[], void *userdata) {
         assert(argc == 2);
         assert(argv);
 
-        r = acquire_systemd_bus(&bus);
+        r = acquire_bus(&bus, NULL);
         if (r < 0)
                 return log_error_errno(r, "Failed to create bus connection: %m");
 
@@ -1401,7 +1475,7 @@ static int get_log_target(int argc, char *argv[], void *userdata) {
         _cleanup_free_ char *target = NULL;
         int r;
 
-        r = acquire_systemd_bus(&bus);
+        r = acquire_bus(&bus, NULL);
         if (r < 0)
                 return log_error_errno(r, "Failed to create bus connection: %m");
 
@@ -1563,7 +1637,7 @@ static int service_watchdogs(int argc, char *argv[], void *userdata) {
         assert(IN_SET(argc, 1, 2));
         assert(argv);
 
-        r = acquire_systemd_bus(&bus);
+        r = acquire_bus(&bus, NULL);
         if (r < 0)
                 return log_error_errno(r, "Failed to create bus connection: %m");
 
@@ -1643,6 +1717,7 @@ static int help(int argc, char *argv[], void *userdata) {
                "  log-level [LEVEL]        Get/set logging threshold for manager\n"
                "  log-target [TARGET]      Get/set logging target for manager\n"
                "  dump                     Output state serialization of service manager\n"
+               "  cat-config               Show configuration file and drop-ins\n"
                "  unit-paths               List load directories for units\n"
                "  syscall-filter [NAME...] Print list of syscalls in seccomp filter\n"
                "  verify FILE...           Check unit files for correctness\n"
@@ -1662,6 +1737,7 @@ static int parse_argv(int argc, char *argv[]) {
                 ARG_VERSION = 0x100,
                 ARG_ORDER,
                 ARG_REQUIRE,
+                ARG_ROOT,
                 ARG_SYSTEM,
                 ARG_USER,
                 ARG_GLOBAL,
@@ -1678,6 +1754,7 @@ static int parse_argv(int argc, char *argv[]) {
                 { "version",      no_argument,       NULL, ARG_VERSION          },
                 { "order",        no_argument,       NULL, ARG_ORDER            },
                 { "require",      no_argument,       NULL, ARG_REQUIRE          },
+                { "root",         required_argument, NULL, ARG_ROOT             },
                 { "system",       no_argument,       NULL, ARG_SYSTEM           },
                 { "user",         no_argument,       NULL, ARG_USER             },
                 { "global",       no_argument,       NULL, ARG_GLOBAL           },
@@ -1706,6 +1783,10 @@ static int parse_argv(int argc, char *argv[]) {
                 case ARG_VERSION:
                         return version();
 
+                case ARG_ROOT:
+                        arg_root = optarg;
+                        break;
+
                 case ARG_SYSTEM:
                         arg_scope = UNIT_FILE_SYSTEM;
                         break;
@@ -1799,6 +1880,11 @@ static int parse_argv(int argc, char *argv[]) {
                 return -EINVAL;
         }
 
+        if (arg_root && !streq_ptr(argv[optind], "cat-config")) {
+                log_error("Option --root is only supported for cat-config right now.");
+                return -EINVAL;
+        }
+
         return 1; /* work to do */
 }
 
@@ -1819,6 +1905,7 @@ int main(int argc, char *argv[]) {
                 { "set-log-target",    2,        2,        0,            set_log_target         },
                 { "get-log-target",    VERB_ANY, 1,        0,            get_log_target         },
                 { "dump",              VERB_ANY, 1,        0,            dump                   },
+                { "cat-config",        2,        VERB_ANY, 0,            cat_config             },
                 { "unit-paths",        1,        1,        0,            dump_unit_paths        },
                 { "syscall-filter",    VERB_ANY, VERB_ANY, 0,            dump_syscall_filters   },
                 { "verify",            2,        VERB_ANY, 0,            do_verify              },
index 47adfb4d0a3c79256990f38219020ca44f782299..5859af0a81b622e60ccbc580f18c2a1529902751 100644 (file)
@@ -30,7 +30,7 @@ _Pragma("GCC diagnostic ignored \"-Wimplicit-fallthrough\"")
 
 // Other compilers
 
-#else  // defined(_MSC_VER)
+#else        // defined(_MSC_VER)
 
 #define BIG_CONSTANT(x) (x##LLU)
 
index 93362dd4857a8299df670573522e3ef92eb7b5e0..6104b4fbe68c62308c1310f46079ca8c48ab86a0 100644 (file)
@@ -18,7 +18,7 @@ typedef unsigned __int64 uint64_t;
 
 // Other compilers
 
-#else  // defined(_MSC_VER)
+#else        // defined(_MSC_VER)
 
 #include <stdint.h>
 
index a30de78dc233ed9931a095caddc89644a7274317..f8c798f31f022f69b8e208be3503bfc0f49aca0f 100644 (file)
@@ -891,7 +891,7 @@ fail:
 
 int calendar_spec_from_string(const char *p, CalendarSpec **spec) {
         const char *utc;
-        CalendarSpec *c;
+        _cleanup_(calendar_spec_freep) CalendarSpec *c = NULL;
         int r;
 
         assert(p);
@@ -937,60 +937,56 @@ int calendar_spec_from_string(const char *p, CalendarSpec **spec) {
                         const char *last_space;
 
                         last_space = strrchr(p, ' ');
-                        if (last_space != NULL && timezone_is_valid(last_space + 1)) {
+                        if (last_space != NULL && timezone_is_valid(last_space + 1, LOG_DEBUG)) {
                                 c->timezone = strdup(last_space + 1);
-                                if (!c->timezone) {
-                                        r = -ENOMEM;
-                                        goto fail;
-                                }
+                                if (!c->timezone)
+                                        return -ENOMEM;
 
                                 p = strndupa(p, last_space - p);
                         }
                 }
         }
 
-        if (isempty(p)) {
-                r = -EINVAL;
-                goto fail;
-        }
+        if (isempty(p))
+                return -EINVAL;
 
         if (strcaseeq(p, "minutely")) {
                 r = const_chain(0, &c->microsecond);
                 if (r < 0)
-                        goto fail;
+                        return r;
 
         } else if (strcaseeq(p, "hourly")) {
                 r = const_chain(0, &c->minute);
                 if (r < 0)
-                        goto fail;
+                        return r;
                 r = const_chain(0, &c->microsecond);
                 if (r < 0)
-                        goto fail;
+                        return r;
 
         } else if (strcaseeq(p, "daily")) {
                 r = const_chain(0, &c->hour);
                 if (r < 0)
-                        goto fail;
+                        return r;
                 r = const_chain(0, &c->minute);
                 if (r < 0)
-                        goto fail;
+                        return r;
                 r = const_chain(0, &c->microsecond);
                 if (r < 0)
-                        goto fail;
+                        return r;
 
         } else if (strcaseeq(p, "monthly")) {
                 r = const_chain(1, &c->day);
                 if (r < 0)
-                        goto fail;
+                        return r;
                 r = const_chain(0, &c->hour);
                 if (r < 0)
-                        goto fail;
+                        return r;
                 r = const_chain(0, &c->minute);
                 if (r < 0)
-                        goto fail;
+                        return r;
                 r = const_chain(0, &c->microsecond);
                 if (r < 0)
-                        goto fail;
+                        return r;
 
         } else if (strcaseeq(p, "annually") ||
                    strcaseeq(p, "yearly") ||
@@ -998,19 +994,19 @@ int calendar_spec_from_string(const char *p, CalendarSpec **spec) {
 
                 r = const_chain(1, &c->month);
                 if (r < 0)
-                        goto fail;
+                        return r;
                 r = const_chain(1, &c->day);
                 if (r < 0)
-                        goto fail;
+                        return r;
                 r = const_chain(0, &c->hour);
                 if (r < 0)
-                        goto fail;
+                        return r;
                 r = const_chain(0, &c->minute);
                 if (r < 0)
-                        goto fail;
+                        return r;
                 r = const_chain(0, &c->microsecond);
                 if (r < 0)
-                        goto fail;
+                        return r;
 
         } else if (strcaseeq(p, "weekly")) {
 
@@ -1018,40 +1014,40 @@ int calendar_spec_from_string(const char *p, CalendarSpec **spec) {
 
                 r = const_chain(0, &c->hour);
                 if (r < 0)
-                        goto fail;
+                        return r;
                 r = const_chain(0, &c->minute);
                 if (r < 0)
-                        goto fail;
+                        return r;
                 r = const_chain(0, &c->microsecond);
                 if (r < 0)
-                        goto fail;
+                        return r;
 
         } else if (strcaseeq(p, "quarterly")) {
 
                 r = const_chain(1, &c->month);
                 if (r < 0)
-                        goto fail;
+                        return r;
                 r = const_chain(4, &c->month);
                 if (r < 0)
-                        goto fail;
+                        return r;
                 r = const_chain(7, &c->month);
                 if (r < 0)
-                        goto fail;
+                        return r;
                 r = const_chain(10, &c->month);
                 if (r < 0)
-                        goto fail;
+                        return r;
                 r = const_chain(1, &c->day);
                 if (r < 0)
-                        goto fail;
+                        return r;
                 r = const_chain(0, &c->hour);
                 if (r < 0)
-                        goto fail;
+                        return r;
                 r = const_chain(0, &c->minute);
                 if (r < 0)
-                        goto fail;
+                        return r;
                 r = const_chain(0, &c->microsecond);
                 if (r < 0)
-                        goto fail;
+                        return r;
 
         } else if (strcaseeq(p, "biannually") ||
                    strcaseeq(p, "bi-annually") ||
@@ -1060,59 +1056,51 @@ int calendar_spec_from_string(const char *p, CalendarSpec **spec) {
 
                 r = const_chain(1, &c->month);
                 if (r < 0)
-                        goto fail;
+                        return r;
                 r = const_chain(7, &c->month);
                 if (r < 0)
-                        goto fail;
+                        return r;
                 r = const_chain(1, &c->day);
                 if (r < 0)
-                        goto fail;
+                        return r;
                 r = const_chain(0, &c->hour);
                 if (r < 0)
-                        goto fail;
+                        return r;
                 r = const_chain(0, &c->minute);
                 if (r < 0)
-                        goto fail;
+                        return r;
                 r = const_chain(0, &c->microsecond);
                 if (r < 0)
-                        goto fail;
+                        return r;
 
         } else {
                 r = parse_weekdays(&p, c);
                 if (r < 0)
-                        goto fail;
+                        return r;
 
                 r = parse_date(&p, c);
                 if (r < 0)
-                        goto fail;
+                        return r;
 
                 if (r == 0) {
                         r = parse_calendar_time(&p, c);
                         if (r < 0)
-                                goto fail;
+                                return r;
                 }
 
-                if (*p != 0) {
-                        r = -EINVAL;
-                        goto fail;
-                }
+                if (*p != 0)
+                        return -EINVAL;
         }
 
         r = calendar_spec_normalize(c);
         if (r < 0)
-                goto fail;
+                return r;
 
-        if (!calendar_spec_valid(c)) {
-                r = -EINVAL;
-                goto fail;
-        }
+        if (!calendar_spec_valid(c))
+                return -EINVAL;
 
-        *spec = c;
+        *spec = TAKE_PTR(c);
         return 0;
-
-fail:
-        calendar_spec_free(c);
-        return r;
 }
 
 static int find_end_of_month(struct tm *tm, bool utc, int day) {
index b5cad5a6e3537d23a185529840d4b168b5a11457..1112dbf2f8830d0769ede8f1ba8b9529632314ae 100644 (file)
@@ -13,6 +13,7 @@
 #include <string.h>
 
 #include "conf-files.h"
+#include "def.h"
 #include "dirent-util.h"
 #include "fd-util.h"
 #include "hashmap.h"
@@ -23,6 +24,7 @@
 #include "stat-util.h"
 #include "string-util.h"
 #include "strv.h"
+#include "terminal-util.h"
 #include "util.h"
 
 static int files_add(Hashmap *h, const char *suffix, const char *root, unsigned flags, const char *path) {
@@ -256,3 +258,71 @@ int conf_files_list_nulstr(char ***strv, const char *suffix, const char *root, u
 
         return conf_files_list_strv_internal(strv, suffix, root, flags, d);
 }
+
+int conf_files_list_with_replacement(
+                const char *root,
+                char **config_dirs,
+                const char *replacement,
+                char ***files,
+                char **replace_file) {
+
+        _cleanup_strv_free_ char **f = NULL;
+        _cleanup_free_ char *p = NULL;
+        int r;
+
+        assert(config_dirs);
+        assert(files);
+        assert(replace_file || !replacement);
+
+        r = conf_files_list_strv(&f, ".conf", root, 0, (const char* const*) config_dirs);
+        if (r < 0)
+                return log_error_errno(r, "Failed to enumerate config files: %m");
+
+        if (replacement) {
+                r = conf_files_insert(&f, root, config_dirs, replacement);
+                if (r < 0)
+                        return log_error_errno(r, "Failed to extend config file list: %m");
+
+                p = path_join(root, replacement, NULL);
+                if (!p)
+                        return log_oom();
+        }
+
+        *files = TAKE_PTR(f);
+        if (replace_file)
+                *replace_file = TAKE_PTR(p);
+        return 0;
+}
+
+int conf_files_cat(const char *root, const char *name) {
+        _cleanup_strv_free_ char **dirs = NULL, **files = NULL;
+        _cleanup_free_ char *path = NULL;
+        const char *dir;
+        char **t;
+        int r;
+
+        NULSTR_FOREACH(dir, CONF_PATHS_NULSTR("")) {
+                assert(endswith(dir, "/"));
+                r = strv_extendf(&dirs, "%s%s.d", dir, name);
+                if (r < 0)
+                        return log_error("Failed to build directory list: %m");
+        }
+
+        r = conf_files_list_strv(&files, ".conf", root, 0, (const char* const*) dirs);
+        if (r < 0)
+                return log_error_errno(r, "Failed to query file list: %m");
+
+        path = path_join(root, "/etc", name);
+        if (!path)
+                return log_oom();
+
+        if (DEBUG_LOGGING) {
+                log_debug("Looking for configuration in:");
+                log_debug("   %s", path);
+                STRV_FOREACH(t, dirs)
+                        log_debug("   %s/*.conf", *t);
+        }
+
+        /* show */
+        return cat_files(path, files, CAT_FLAGS_MAIN_FILE_OPTIONAL);
+}
index b902c3a3b35aae5b32416fc00c383d8a31755619..2dd1b272caa8130e551079856a277d279540a65a 100644 (file)
@@ -17,3 +17,10 @@ int conf_files_list_strv(char ***ret, const char *suffix, const char *root, unsi
 int conf_files_list_nulstr(char ***ret, const char *suffix, const char *root, unsigned flags, const char *dirs);
 int conf_files_insert(char ***strv, const char *root, char **dirs, const char *path);
 int conf_files_insert_nulstr(char ***strv, const char *root, const char *dirs, const char *path);
+int conf_files_list_with_replacement(
+                const char *root,
+                char **config_dirs,
+                const char *replacement,
+                char ***files,
+                char **replace_file);
+int conf_files_cat(const char *root, const char *name);
index 0ffd81fe39ec3385f5490f055e07681ab07edfd2..559721754a83fab7ad7b4947e77f389e5cac01d9 100644 (file)
 #define NOTIFY_BUFFER_MAX PIPE_BUF
 
 #if HAVE_SPLIT_USR
-#  define _CONF_PATHS_SPLIT_USR(n) "/lib/" n "\0"
+#  define _CONF_PATHS_SPLIT_USR_NULSTR(n) "/lib/" n "\0"
+#  define _CONF_PATHS_SPLIT_USR(n) , "/lib/" n
 #else
+#  define _CONF_PATHS_SPLIT_USR_NULSTR(n)
 #  define _CONF_PATHS_SPLIT_USR(n)
 #endif
 
         "/run/" n "\0"                          \
         "/usr/local/lib/" n "\0"                \
         "/usr/lib/" n "\0"                      \
-        _CONF_PATHS_SPLIT_USR(n)
+        _CONF_PATHS_SPLIT_USR_NULSTR(n)
+
+#define CONF_PATHS_STRV(n)                      \
+        STRV_MAKE(                              \
+                "/etc/" n,                      \
+                "/run/" n,                      \
+                "/usr/local/lib/" n,            \
+                "/usr/lib/" n                   \
+                _CONF_PATHS_SPLIT_USR(n))
 
 #define LONG_LINE_MAX (1U*1024U*1024U)
index 0ebf66c57244c0a795445e90ed6d6ebdf6014e77..c17c5f7baead18e95bd27608d5661566ed2f8b45 100644 (file)
@@ -417,7 +417,8 @@ int strv_env_replace(char ***l, char *p) {
 
 char **strv_env_set(char **x, const char *p) {
 
-        char **k, **r;
+        char **k;
+        _cleanup_strv_free_ char **r = NULL;
         char* m[2] = { (char*) p, NULL };
 
         /* Overrides the env var setting of p, returns a new copy */
@@ -428,18 +429,14 @@ char **strv_env_set(char **x, const char *p) {
 
         k = r;
         if (env_append(r, &k, x) < 0)
-                goto fail;
+                return NULL;
 
         if (env_append(r, &k, m) < 0)
-                goto fail;
+                return NULL;
 
         *k = NULL;
 
-        return r;
-
-fail:
-        strv_free(r);
-        return NULL;
+        return TAKE_PTR(r);
 }
 
 char *strv_env_get_n(char **l, const char *name, size_t k, unsigned flags) {
index e6ca7fa52690f57f407b01bdfa232989b05e2c72..99ef936e8430e8fd032116d9d4f797d085119d7d 100644 (file)
@@ -33,19 +33,23 @@ char* ether_addr_to_string(const struct ether_addr *addr, char buffer[ETHER_ADDR
         return buffer;
 }
 
-bool ether_addr_equal(const struct ether_addr *a, const struct ether_addr *b) {
+int ether_addr_compare(const void *a, const void *b) {
         assert(a);
         assert(b);
 
-        return  a->ether_addr_octet[0] == b->ether_addr_octet[0] &&
-                a->ether_addr_octet[1] == b->ether_addr_octet[1] &&
-                a->ether_addr_octet[2] == b->ether_addr_octet[2] &&
-                a->ether_addr_octet[3] == b->ether_addr_octet[3] &&
-                a->ether_addr_octet[4] == b->ether_addr_octet[4] &&
-                a->ether_addr_octet[5] == b->ether_addr_octet[5];
+        return memcmp(a, b, ETH_ALEN);
 }
 
-int ether_addr_from_string(const char *s, struct ether_addr *ret, size_t *offset) {
+static void ether_addr_hash_func(const void *p, struct siphash *state) {
+        siphash24_compress(p, sizeof(struct ether_addr), state);
+}
+
+const struct hash_ops ether_addr_hash_ops = {
+        .hash = ether_addr_hash_func,
+        .compare = ether_addr_compare
+};
+
+int ether_addr_from_string(const char *s, struct ether_addr *ret) {
         size_t pos = 0, n, field;
         char sep = '\0';
         const char *hex = HEXDIGITS, *hexoff;
@@ -84,31 +88,35 @@ int ether_addr_from_string(const char *s, struct ether_addr *ret, size_t *offset
         assert(s);
         assert(ret);
 
+        s += strspn(s, WHITESPACE);
         sep = s[strspn(s, hex)];
-        if (sep == '\n')
-                return -EINVAL;
-        if (!strchr(":.-", sep))
-                return -EINVAL;
 
         if (sep == '.') {
                 uint16_t shorts[3] = { 0 };
 
                 parse_fields(shorts);
 
+                if (s[pos] != '\0')
+                        return -EINVAL;
+
                 for (n = 0; n < ELEMENTSOF(shorts); n++) {
                         ret->ether_addr_octet[2*n] = ((shorts[n] & (uint16_t)0xff00) >> 8);
                         ret->ether_addr_octet[2*n + 1] = (shorts[n] & (uint16_t)0x00ff);
                 }
-        } else {
-                struct ether_addr out = { .ether_addr_octet = { 0 } };
+
+        } else if (IN_SET(sep, ':', '-')) {
+                struct ether_addr out = ETHER_ADDR_NULL;
 
                 parse_fields(out.ether_addr_octet);
 
+                if (s[pos] != '\0')
+                        return -EINVAL;
+
                 for (n = 0; n < ELEMENTSOF(out.ether_addr_octet); n++)
                         ret->ether_addr_octet[n] = out.ether_addr_octet[n];
-        }
 
-        if (offset)
-                *offset = pos;
+        } else
+                return -EINVAL;
+
         return 0;
 }
index 29d7f362944f1347c65e50ba02376d75a0fbc320..f7e0de54cc8c0c92b2cd3599df2a33dc83947a6d 100644 (file)
 #include <net/ethernet.h>
 #include <stdbool.h>
 
+#include "hash-funcs.h"
+
 #define ETHER_ADDR_FORMAT_STR "%02X%02X%02X%02X%02X%02X"
 #define ETHER_ADDR_FORMAT_VAL(x) (x).ether_addr_octet[0], (x).ether_addr_octet[1], (x).ether_addr_octet[2], (x).ether_addr_octet[3], (x).ether_addr_octet[4], (x).ether_addr_octet[5]
 
 #define ETHER_ADDR_TO_STRING_MAX (3*6)
 char* ether_addr_to_string(const struct ether_addr *addr, char buffer[ETHER_ADDR_TO_STRING_MAX]);
 
-bool ether_addr_equal(const struct ether_addr *a, const struct ether_addr *b);
+int ether_addr_compare(const void *a, const void *b);
+static inline bool ether_addr_equal(const struct ether_addr *a, const struct ether_addr *b) {
+        return ether_addr_compare(a, b) == 0;
+}
 
 #define ETHER_ADDR_NULL ((const struct ether_addr){})
 
@@ -24,4 +29,6 @@ static inline bool ether_addr_is_null(const struct ether_addr *addr) {
         return ether_addr_equal(addr, &ETHER_ADDR_NULL);
 }
 
-int ether_addr_from_string(const char *s, struct ether_addr *ret, size_t *offset);
+int ether_addr_from_string(const char *s, struct ether_addr *ret);
+
+extern const struct hash_ops ether_addr_hash_ops;
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 ae2c6238c4e7bc18655252ae64c3ec78f3b4c95f..582c5b86a4eba1f132078d755c491641a8efb8dc 100644 (file)
@@ -648,6 +648,7 @@ int table_set_display(Table *t, size_t first_column, ...) {
                         break;
 
         }
+        va_end(ap);
 
         return 0;
 }
@@ -676,6 +677,7 @@ int table_set_sort(Table *t, size_t first_column, ...) {
                 if (column == (size_t) -1)
                         break;
         }
+        va_end(ap);
 
         return 0;
 }
index 13dccfef545307978caedaa392c29f71c85b0ed1..a0d7a43d274c35b570f038acb020943788db8fc2 100644 (file)
@@ -242,7 +242,7 @@ int fchmod_umask(int fd, mode_t m) {
 }
 
 int fchmod_opath(int fd, mode_t m) {
-        char procfs_path[strlen("/proc/self/fd/") + DECIMAL_STR_MAX(int)];
+        char procfs_path[STRLEN("/proc/self/fd/") + DECIMAL_STR_MAX(int)];
 
         /* This function operates also on fd that might have been opened with
          * O_PATH. Indeed fchmodat() doesn't have the AT_EMPTY_PATH flag like
@@ -919,25 +919,12 @@ int chase_symlinks(const char *path, const char *original_root, unsigned flags,
         return exists;
 
 chased_one:
-
         if (ret) {
                 char *c;
 
-                if (done) {
-                        if (todo) {
-                                c = strjoin(done, todo);
-                                if (!c)
-                                        return -ENOMEM;
-                        } else
-                                c = TAKE_PTR(done);
-                } else {
-                        if (todo)
-                                c = strdup(todo);
-                        else
-                                c = strdup("/");
-                        if (!c)
-                                return -ENOMEM;
-                }
+                c = strjoin(strempty(done), todo);
+                if (!c)
+                        return -ENOMEM;
 
                 *ret = c;
         }
@@ -1079,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_noerrno(*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 7ab5c5f70b14b35a78d54a299de29807c99946a0..b3ea05ce53e6d1b315edd429ee62027242d5aa6d 100644 (file)
@@ -77,33 +77,69 @@ char *hexmem(const void *p, size_t l) {
         return r;
 }
 
-int unhexmem(const char *p, size_t l, void **mem, size_t *len) {
-        _cleanup_free_ uint8_t *r = NULL;
-        uint8_t *z;
+static int unhex_next(const char **p, size_t *l) {
+        int r;
+
+        assert(p);
+        assert(l);
+
+        /* Find the next non-whitespace character, and decode it. We
+         * greedily skip all preceeding and all following whitespace. */
+
+        for (;;) {
+                if (*l == 0)
+                        return -EPIPE;
+
+                if (!strchr(WHITESPACE, **p))
+                        break;
+
+                /* Skip leading whitespace */
+                (*p)++, (*l)--;
+        }
+
+        r = unhexchar(**p);
+        if (r < 0)
+                return r;
+
+        for (;;) {
+                (*p)++, (*l)--;
+
+                if (*l == 0 || !strchr(WHITESPACE, **p))
+                        break;
+
+                /* Skip following whitespace */
+        }
+
+        return r;
+}
+
+int unhexmem(const char *p, size_t l, void **ret, size_t *ret_len) {
+        _cleanup_free_ uint8_t *buf = NULL;
         const char *x;
+        uint8_t *z;
 
-        assert(mem);
-        assert(len);
+        assert(ret);
+        assert(ret_len);
         assert(p || l == 0);
 
         if (l == (size_t) -1)
                 l = strlen(p);
 
-        if (l % 2 != 0)
-                return -EINVAL;
-
-        z = r = malloc((l + 1) / 2 + 1);
-        if (!r)
+        /* Note that the calculation of memory size is an upper boundary, as we ignore whitespace while decoding */
+        buf = malloc((l + 1) / 2 + 1);
+        if (!buf)
                 return -ENOMEM;
 
-        for (x = p; x < p + l; x += 2) {
+        for (x = p, z = buf;;) {
                 int a, b;
 
-                a = unhexchar(x[0]);
+                a = unhex_next(&x, &l);
+                if (a == -EPIPE) /* End of string */
+                        break;
                 if (a < 0)
                         return a;
 
-                b = unhexchar(x[1]);
+                b = unhex_next(&x, &l);
                 if (b < 0)
                         return b;
 
@@ -112,8 +148,8 @@ int unhexmem(const char *p, size_t l, void **mem, size_t *len) {
 
         *z = 0;
 
-        *mem = TAKE_PTR(r);
-        *len = (l + 1) / 2;
+        *ret_len = (size_t) (z - buf);
+        *ret = TAKE_PTR(buf);
 
         return 0;
 }
@@ -181,7 +217,7 @@ char *base32hexmem(const void *p, size_t l, bool padding) {
 
         for (x = p; x < (const uint8_t*) p + (l / 5) * 5; x += 5) {
                 /* x[0] == XXXXXXXX; x[1] == YYYYYYYY; x[2] == ZZZZZZZZ
-                   x[3] == QQQQQQQQ; x[4] == WWWWWWWW */
+                 * x[3] == QQQQQQQQ; x[4] == WWWWWWWW */
                 *(z++) = base32hexchar(x[0] >> 3);                    /* 000XXXXX */
                 *(z++) = base32hexchar((x[0] & 7) << 2 | x[1] >> 6);  /* 000XXXYY */
                 *(z++) = base32hexchar((x[1] & 63) >> 1);             /* 000YYYYY */
@@ -281,7 +317,7 @@ int unbase32hexmem(const char *p, size_t l, bool padding, void **mem, size_t *_l
         }
 
         /* a group of eight input bytes needs five output bytes, in case of
-           padding we need to add some extra bytes */
+         * padding we need to add some extra bytes */
         len = (l / 8) * 5;
 
         switch (l % 8) {
@@ -309,7 +345,7 @@ int unbase32hexmem(const char *p, size_t l, bool padding, void **mem, size_t *_l
 
         for (x = p; x < p + (l / 8) * 8; x += 8) {
                 /* a == 000XXXXX; b == 000YYYYY; c == 000ZZZZZ; d == 000WWWWW
-                   e == 000SSSSS; f == 000QQQQQ; g == 000VVVVV; h == 000RRRRR */
+                 * e == 000SSSSS; f == 000QQQQQ; g == 000VVVVV; h == 000RRRRR */
                 a = unbase32hexchar(x[0]);
                 if (a < 0)
                         return -EINVAL;
@@ -665,7 +701,7 @@ int unbase64mem(const char *p, size_t l, void **ret, size_t *ret_size) {
                 l = strlen(p);
 
         /* A group of four input bytes needs three output bytes, in case of padding we need to add two or three extra
-           bytes. Note that this calculation is an upper boundary, as we ignore whitespace while decoding */
+         * bytes. Note that this calculation is an upper boundary, as we ignore whitespace while decoding */
         len = (l / 4) * 3 + (l % 4 != 0 ? (l % 4) - 1 : 0);
 
         buf = malloc(len + 1);
@@ -733,9 +769,7 @@ int unbase64mem(const char *p, size_t l, void **ret, size_t *ret_size) {
 
         *z = 0;
 
-        if (ret_size)
-                *ret_size = (size_t) (z - buf);
-
+        *ret_size = (size_t) (z - buf);
         *ret = TAKE_PTR(buf);
 
         return 0;
index 6f4424201105cbcaaf519b382f39bdb11011fa8a..5db65f276f75c3f28ce0224087a60029e9f81a0b 100644 (file)
@@ -1330,3 +1330,20 @@ int log_emergency_level(void) {
 
         return getpid_cached() == 1 ? LOG_EMERG : LOG_ERR;
 }
+
+int log_dup_console(void) {
+        int copy;
+
+        /* Duplicate the fd we use for fd logging if it's < 3 and use the copy from now on. This call is useful
+         * whenever we want to continue logging through the original fd, but want to rearrange stderr. */
+
+        if (console_fd >= 3)
+                return 0;
+
+        copy = fcntl(console_fd, F_DUPFD_CLOEXEC, 3);
+        if (copy < 0)
+                return -errno;
+
+        console_fd = copy;
+        return 0;
+}
index 63cfd298ec17338b6c57bafed0c554062884988e..6a8cf6375f11926e4355968c40d57cc35339ab5f 100644 (file)
@@ -284,6 +284,8 @@ void log_set_open_when_needed(bool b);
  * stderr, the console or kmsg */
 void log_set_prohibit_ipc(bool b);
 
+int log_dup_console(void);
+
 int log_syntax_internal(
                 const char *unit,
                 int level,
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..ba0c0bd8f967f6910c88e50d23d7546bb2a2fdcf 100644 (file)
@@ -29,7 +29,6 @@ static struct mempool pool_name = { \
         .at_least = alloc_at_least, \
 }
 
-
-#ifdef VALGRIND
+#if VALGRIND
 void mempool_drop(struct mempool *mp);
 #endif
index cff1b9d18ff46b6e80af84a33567f8e8475ea4a9..69c525dcdc23fbae7bb69359584882beb5283e6e 100644 (file)
@@ -302,6 +302,9 @@ foreach item : [['af',     af_list_txt,     'af',         ''],
 endforeach
 
 basic_sources += [missing_h] + generated_gperf_headers
+basic_gcrypt_sources = files(
+        'gcrypt-util.c',
+        'gcrypt-util.h')
 
 libbasic = static_library(
         'basic',
@@ -319,8 +322,7 @@ libbasic = static_library(
 # unnecessary linking to libgcrypt.
 libbasic_gcrypt = static_library(
         'basic-gcrypt',
-        'gcrypt-util.c',
-        'gcrypt-util.h',
+        basic_gcrypt_sources,
         include_directories : includes,
         dependencies : [libgcrypt],
         c_args : ['-fvisibility=default'])
index 9fe750ae2888d348d3e012572f57b567c6a8d499..e714078f31ed50d7c90ffa48545f0ba4dc64fffb 100644 (file)
@@ -329,7 +329,6 @@ struct btrfs_ioctl_search_header {
         __u32 len;
 };
 
-
 struct btrfs_ioctl_search_args {
         struct btrfs_ioctl_search_key key;
         char buf[BTRFS_SEARCH_ARGS_BUFSIZE];
index 42ada30d524e529562216a7e390b8650ab08c833..89ca1f062a92eac46b08ec3c500ce1350c29ba95 100644 (file)
@@ -256,7 +256,6 @@ static inline int missing_kcmp(pid_t pid1, pid_t pid2, int type, unsigned long i
 #  define kcmp missing_kcmp
 #endif
 
-
 /* ======================================================================= */
 
 #if !HAVE_KEYCTL
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 2ecb1430142afd19550f6b2a32e2372f319ec47b..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;
 }
 
@@ -918,7 +919,7 @@ int systemd_installation_has_version(const char *root, unsigned minimal_version)
                 if (r < 0)
                         return r;
 
-                assert_se((c = endswith(path, "*.so")));
+                assert_se(c = endswith(path, "*.so"));
                 *c = '\0'; /* truncate the glob part */
 
                 STRV_FOREACH(name, names) {
index fd3143d9acce8d5ac08fba9989cdb37b56d50277..134e1ebc98f1f8c2835b3ae04075f01cc060f0a7 100644 (file)
@@ -164,3 +164,6 @@ static inline const char *skip_dev_prefix(const char *p) {
 }
 
 bool empty_or_root(const char *root);
+static inline const char *empty_to_root(const char *path) {
+        return isempty(path) ? "/" : path;
+}
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 6598b1a812e6a4363a93d2fa02778ccd1bb56b96..6804364f302bd178e09447ac768c426d18e2433a 100644 (file)
@@ -13,7 +13,7 @@
 /* Modelled after Linux' lib/ratelimit.c by Dave Young
  * <hidave.darkstar@gmail.com>, which is licensed GPLv2. */
 
-bool ratelimit_test(RateLimit *r) {
+bool ratelimit_below(RateLimit *r) {
         usec_t ts;
 
         assert(r);
index 6abab8f2909ee34f47a27fd3230bcbf6ec4ebe29..5a9aeb6486305a3810a0909f38c7546365183f2c 100644 (file)
@@ -43,4 +43,4 @@ typedef struct RateLimit {
                 _r->begin = 0;                           \
         } while (false)
 
-bool ratelimit_test(RateLimit *r);
+bool ratelimit_below(RateLimit *r);
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 })
index 2f5c2a92be93373ad739dcb6bd81200edbd37189..91474ad95cf89ca6176139e5aadbb89dcbeb5d76 100644 (file)
@@ -13,6 +13,7 @@
 #include <sys/statfs.h>
 #include <unistd.h>
 
+#include "alloc-util.h"
 #include "btrfs-util.h"
 #include "cgroup-util.h"
 #include "dirent-util.h"
@@ -49,13 +50,15 @@ int rm_rf_children(int fd, RemoveFlags flags, struct stat *root_dev) {
                 }
 
                 if (is_physical_fs(&sfs)) {
-                        /* We refuse to clean physical file systems
-                         * with this call, unless explicitly
-                         * requested. This is extra paranoia just to
-                         * be sure we never ever remove non-state
-                         * data */
+                        /* We refuse to clean physical file systems with this call,
+                         * unless explicitly requested. This is extra paranoia just
+                         * to be sure we never ever remove non-state data. */
+                        _cleanup_free_ char *path = NULL;
+
+                        (void) fd_get_path(fd, &path);
+                        log_error("Attempted to remove disk file system under \"%s\", and we can't allow that.",
+                                  strna(path));
 
-                        log_error("Attempted to remove disk file system, and we can't allow that.");
                         safe_close(fd);
                         return -EPERM;
                 }
@@ -171,7 +174,7 @@ int rm_rf(const char *path, RemoveFlags flags) {
          * call. This is extra paranoia to never cause a really
          * seriously broken system. */
         if (path_equal_or_files_same(path, "/", AT_SYMLINK_NOFOLLOW)) {
-                log_error("Attempted to remove entire root file system, and we can't allow that.");
+                log_error("Attempted to remove entire root file system (\"%s\"), and we can't allow that.", path);
                 return -EPERM;
         }
 
@@ -189,7 +192,6 @@ int rm_rf(const char *path, RemoveFlags flags) {
 
         fd = open(path, O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|O_NOFOLLOW|O_NOATIME);
         if (fd < 0) {
-
                 if (!IN_SET(errno, ENOTDIR, ELOOP))
                         return -errno;
 
@@ -198,7 +200,7 @@ int rm_rf(const char *path, RemoveFlags flags) {
                                 return -errno;
 
                         if (is_physical_fs(&s)) {
-                                log_error("Attempted to remove disk file system, and we can't allow that.");
+                                log_error("Attempted to remove files from a disk file system under \"%s\", refusing.", path);
                                 return -EPERM;
                         }
                 }
index 9104bc7e933b85d5a74a6e15f915c1abcca2e6d1..84c2e4bfa582221caf904ce8e71c34d22d3ebc77 100644 (file)
@@ -11,6 +11,8 @@
 #include <stdint.h>
 #include <sys/types.h>
 
+#include "macro.h"
+
 struct strbuf {
         char *buf;
         size_t len;
@@ -40,3 +42,4 @@ struct strbuf *strbuf_new(void);
 ssize_t strbuf_add_string(struct strbuf *str, const char *s, size_t len);
 void strbuf_complete(struct strbuf *str);
 void strbuf_cleanup(struct strbuf *str);
+DEFINE_TRIVIAL_CLEANUP_FUNC(struct strbuf*, strbuf_cleanup);
index a39206fb9445d973bfb671cb9b0ea127c3c8d924..1786bcfda00294ebdc32d25d823a2991606f6ad1 100644 (file)
@@ -77,7 +77,6 @@ ssize_t string_table_lookup(const char * const *table, size_t len, const char *k
                 return (type) -1;                                       \
         }                                                               \
 
-
 #define _DEFINE_STRING_TABLE_LOOKUP(name,type,scope)                    \
         _DEFINE_STRING_TABLE_LOOKUP_TO_STRING(name,type,scope)          \
         _DEFINE_STRING_TABLE_LOOKUP_FROM_STRING(name,type,scope)
@@ -102,3 +101,18 @@ ssize_t string_table_lookup(const char * const *table, size_t len, const char *k
         _DEFINE_STRING_TABLE_LOOKUP_TO_STRING_FALLBACK(name,type,max,static)
 #define DEFINE_PRIVATE_STRING_TABLE_LOOKUP_FROM_STRING_FALLBACK(name,type,max) \
         _DEFINE_STRING_TABLE_LOOKUP_FROM_STRING_FALLBACK(name,type,max,static)
+
+#define DUMP_STRING_TABLE(name,type,max)                                \
+        do {                                                            \
+                type _k;                                                \
+                flockfile(stdout);                                      \
+                for (_k = 0; _k < (max); _k++) {                        \
+                        const char *_t;                                 \
+                        _t = name##_to_string(_k);                      \
+                        if (!_t)                                        \
+                                continue;                               \
+                        fputs_unlocked(_t, stdout);                     \
+                        fputc_unlocked('\n', stdout);                   \
+                }                                                       \
+                funlockfile(stdout);                                    \
+        } while(false)
index 3004b924bd44f45a86709c2671821ba2be66e0e8..5a10eeabfe90371f1fbd4a2ed13b32dfcb900dd3 100644 (file)
@@ -58,7 +58,7 @@ static inline const char *empty_to_null(const char *p) {
         return isempty(p) ? NULL : p;
 }
 
-static inline const char *strdash_if_empty(const char *str) {
+static inline const char *empty_to_dash(const char *str) {
         return isempty(str) ? "-" : str;
 }
 
index cb91f239e8a6e3d25d4e6cdf009bf53e6bc2fa45..47ab0ad07f1177ae51651a3526d185f1ff61cf00 100644 (file)
@@ -121,7 +121,7 @@ size_t strv_length(char * const *l) {
 
 char **strv_new_ap(const char *x, va_list ap) {
         const char *s;
-        char **a;
+        _cleanup_strv_free_ char **a = NULL;
         size_t n = 0, i = 0;
         va_list aq;
 
@@ -152,7 +152,7 @@ char **strv_new_ap(const char *x, va_list ap) {
                 if (x != STRV_IGNORE) {
                         a[i] = strdup(x);
                         if (!a[i])
-                                goto fail;
+                                return NULL;
                         i++;
                 }
 
@@ -163,7 +163,7 @@ char **strv_new_ap(const char *x, va_list ap) {
 
                         a[i] = strdup(s);
                         if (!a[i])
-                                goto fail;
+                                return NULL;
 
                         i++;
                 }
@@ -171,11 +171,7 @@ char **strv_new_ap(const char *x, va_list ap) {
 
         a[i] = NULL;
 
-        return a;
-
-fail:
-        strv_free(a);
-        return NULL;
+        return TAKE_PTR(a);
 }
 
 char **strv_new(const char *x, ...) {
index 99213e0f35b5b9ce8f58293cd87b874cf11b78e5..7f49f92ad86cf8912007ce8817dc8ada1a406e69 100644 (file)
@@ -7,7 +7,6 @@
   Copyright 2013 Kay Sievers
 ***/
 
-
 #include <stddef.h>
 
 #include "macro.h"
index 2bf0f4f86d8c60a04b53124823eb600caa3a405c..fa90a466d219ca0afab42175f8b7a940fa0099d6 100644 (file)
@@ -28,6 +28,8 @@
 #include <unistd.h>
 
 #include "alloc-util.h"
+#include "copy.h"
+#include "def.h"
 #include "env-util.h"
 #include "fd-util.h"
 #include "fileio.h"
@@ -1362,3 +1364,79 @@ int terminal_urlify_path(const char *path, const char *text, char **ret) {
 
         return terminal_urlify(url, text, ret);
 }
+
+static int cat_file(const char *filename, bool newline) {
+        _cleanup_fclose_ FILE *f = NULL;
+        int r;
+
+        f = fopen(filename, "re");
+        if (!f)
+                return -errno;
+
+        printf("%s%s# %s%s\n",
+               newline ? "\n" : "",
+               ansi_highlight_blue(),
+               filename,
+               ansi_normal());
+        fflush(stdout);
+
+        for (;;) {
+                _cleanup_free_ char *line = NULL;
+
+                r = read_line(f, LONG_LINE_MAX, &line);
+                if (r < 0)
+                        return log_error_errno(r, "Failed to read \"%s\": %m", filename);
+                if (r == 0)
+                        break;
+
+                puts(line);
+        }
+
+        return 0;
+}
+
+int cat_files(const char *file, char **dropins, CatFlags flags) {
+        char **path;
+        int r;
+
+        if (file) {
+                r = cat_file(file, false);
+                if (r == -ENOENT && (flags & CAT_FLAGS_MAIN_FILE_OPTIONAL))
+                        printf("%s# config file %s not found%s\n",
+                               ansi_highlight_magenta(),
+                               file,
+                               ansi_normal());
+                else if (r < 0)
+                        return log_warning_errno(r, "Failed to cat %s: %m", file);
+        }
+
+        STRV_FOREACH(path, dropins) {
+                r = cat_file(*path, file || path != dropins);
+                if (r < 0)
+                        return log_warning_errno(r, "Failed to cat %s: %m", *path);
+        }
+
+        return 0;
+}
+
+void print_separator(void) {
+
+        /* Outputs a separator line that resolves to whitespace when copied from the terminal. We do that by outputting
+         * one line filled with spaces with ANSI underline set, followed by a second (empty) line. */
+
+        if (underline_enabled()) {
+                size_t i, c;
+
+                c = columns();
+
+                flockfile(stdout);
+                fputs_unlocked(ANSI_UNDERLINE, stdout);
+
+                for (i = 0; i < c; i++)
+                        fputc_unlocked(' ', stdout);
+
+                fputs_unlocked(ANSI_NORMAL "\n\n", stdout);
+                funlockfile(stdout);
+        } else
+                fputs("\n\n", stdout);
+}
index ad6ee338edff17886370288fb9495284e27e693e..798bab6c266bc94dfb49bdd3ef16f262beff2dff 100644 (file)
@@ -133,6 +133,7 @@ DEFINE_ANSI_FUNC(highlight_red,              HIGHLIGHT_RED);
 DEFINE_ANSI_FUNC(highlight_green,            HIGHLIGHT_GREEN);
 DEFINE_ANSI_FUNC(highlight_yellow,           HIGHLIGHT_YELLOW);
 DEFINE_ANSI_FUNC(highlight_blue,             HIGHLIGHT_BLUE);
+DEFINE_ANSI_FUNC(highlight_magenta,          HIGHLIGHT_MAGENTA);
 DEFINE_ANSI_FUNC(normal,                     NORMAL);
 
 DEFINE_ANSI_FUNC_UNDERLINE(underline,                  UNDERLINE, NORMAL);
@@ -159,3 +160,11 @@ int vt_reset_keyboard(int fd);
 
 int terminal_urlify(const char *url, const char *text, char **ret);
 int terminal_urlify_path(const char *path, const char *text, char **ret);
+
+typedef enum CatFlags {
+        CAT_FLAGS_MAIN_FILE_OPTIONAL = 1 << 1,
+} CatFlags;
+
+int cat_files(const char *file, char **dropins, CatFlags flags);
+
+void print_separator(void);
index 0880d00ef36e416a1838d4299126674b1214095d..5d278d42cb83e1d02ba383c4b1e1ff07fdfe56a9 100644 (file)
 #include "fd-util.h"
 #include "fileio.h"
 #include "fs-util.h"
+#include "io-util.h"
 #include "log.h"
 #include "macro.h"
 #include "parse-util.h"
 #include "path-util.h"
 #include "process-util.h"
+#include "stat-util.h"
 #include "string-util.h"
 #include "strv.h"
 #include "time-util.h"
@@ -614,8 +616,7 @@ static int parse_timestamp_impl(const char *t, usec_t *usec, bool with_tz) {
         int r, weekday = -1, dst = -1;
         size_t i;
 
-        /*
-         * Allowed syntaxes:
+        /* Allowed syntaxes:
          *
          *   2012-09-22 16:34:22
          *   2012-09-22 16:34     (seconds will be set to 0)
@@ -629,7 +630,6 @@ static int parse_timestamp_impl(const char *t, usec_t *usec, bool with_tz) {
          *   +5min
          *   -5days
          *   @2147483647          (seconds since epoch)
-         *
          */
 
         assert(t);
@@ -688,10 +688,10 @@ static int parse_timestamp_impl(const char *t, usec_t *usec, bool with_tz) {
                         tzset();
 
                         /* See if the timestamp is suffixed by either the DST or non-DST local timezone. Note that we only
-                        * support the local timezones here, nothing else. Not because we wouldn't want to, but simply because
-                        * there are no nice APIs available to cover this. By accepting the local time zone strings, we make
-                        * sure that all timestamps written by format_timestamp() can be parsed correctly, even though we don't
-                        * support arbitrary timezone specifications.  */
+                         * support the local timezones here, nothing else. Not because we wouldn't want to, but simply because
+                         * there are no nice APIs available to cover this. By accepting the local time zone strings, we make
+                         * sure that all timestamps written by format_timestamp() can be parsed correctly, even though we don't
+                         * support arbitrary timezone specifications. */
 
                         for (j = 0; j <= 1; j++) {
 
@@ -877,7 +877,7 @@ int parse_timestamp(const char *t, usec_t *usec) {
         int r;
 
         last_space = strrchr(t, ' ');
-        if (last_space != NULL && timezone_is_valid(last_space + 1))
+        if (last_space != NULL && timezone_is_valid(last_space + 1, LOG_DEBUG))
                 tz = last_space + 1;
 
         if (!tz || endswith_no_case(t, " UTC"))
@@ -903,10 +903,10 @@ int parse_timestamp(const char *t, usec_t *usec) {
                 tzset();
 
                 /* If there is a timezone that matches the tzname fields, leave the parsing to the implementation.
-                 * Otherwise just cut it off */
+                 * Otherwise just cut it off. */
                 with_tz = !STR_IN_SET(tz, tzname[0], tzname[1]);
 
-                /*cut off the timezone if we dont need it*/
+                /* Cut off the timezone if we dont need it. */
                 if (with_tz)
                         t = strndupa(t, last_space - t);
 
@@ -1275,10 +1275,12 @@ int get_timezones(char ***ret) {
         return 0;
 }
 
-bool timezone_is_valid(const char *name) {
+bool timezone_is_valid(const char *name, int log_level) {
         bool slash = false;
         const char *p, *t;
-        struct stat st;
+        _cleanup_close_ int fd = -1;
+        char buf[4];
+        int r;
 
         if (isempty(name))
                 return false;
@@ -1307,11 +1309,30 @@ bool timezone_is_valid(const char *name) {
                 return false;
 
         t = strjoina("/usr/share/zoneinfo/", name);
-        if (stat(t, &st) < 0)
+
+        fd = open(t, O_RDONLY|O_CLOEXEC);
+        if (fd < 0) {
+                log_full_errno(log_level, errno, "Failed to open timezone file '%s': %m", t);
                 return false;
+        }
 
-        if (!S_ISREG(st.st_mode))
+        r = fd_verify_regular(fd);
+        if (r < 0) {
+                log_full_errno(log_level, r, "Timezone file '%s' is not  a regular file: %m", t);
                 return false;
+        }
+
+        r = loop_read_exact(fd, buf, 4, false);
+        if (r < 0) {
+                log_full_errno(log_level, r, "Failed to read from timezone file '%s': %m", t);
+                return false;
+        }
+
+        /* Magic from tzfile(5) */
+        if (memcmp(buf, "TZif", 4) != 0) {
+                log_full(log_level, "Timezone file '%s' has wrong magic bytes", t);
+                return false;
+        }
 
         return true;
 }
@@ -1382,7 +1403,7 @@ int get_timezone(char **tz) {
         if (!e)
                 return -EINVAL;
 
-        if (!timezone_is_valid(e))
+        if (!timezone_is_valid(e, LOG_DEBUG))
                 return -EINVAL;
 
         z = strdup(e);
index 5b2674a4b6797d53cee3affde425314ff6e115a6..e720688c2b5ba05fd4c58096100b78e8d23ab843 100644 (file)
@@ -128,7 +128,7 @@ int parse_nsec(const char *t, nsec_t *nsec);
 bool ntp_synced(void);
 
 int get_timezones(char ***l);
-bool timezone_is_valid(const char *name);
+bool timezone_is_valid(const char *name, int log_level);
 
 bool clock_boottime_supported(void);
 bool clock_supported(clockid_t clock);
index aa4a3f3ed60e4a7db902b39b9d8881e8179a002e..68aaa21a8d32d4042dc7c76f0ac3a4a4b643056f 100644 (file)
@@ -405,6 +405,7 @@ uint64_t physical_memory(void) {
         uint64_t mem, lim;
         size_t ps;
         long sc;
+        int r;
 
         /* We return this as uint64_t in case we are running as 32bit process on a 64bit kernel with huge amounts of
          * memory.
@@ -418,13 +419,40 @@ uint64_t physical_memory(void) {
         ps = page_size();
         mem = (uint64_t) sc * (uint64_t) ps;
 
-        if (cg_get_root_path(&root) < 0)
+        r = cg_get_root_path(&root);
+        if (r < 0) {
+                log_debug_errno(r, "Failed to determine root cgroup, ignoring cgroup memory limit: %m");
                 return mem;
+        }
 
-        if (cg_get_attribute("memory", root, "memory.limit_in_bytes", &value))
+        r = cg_all_unified();
+        if (r < 0) {
+                log_debug_errno(r, "Failed to determine root unified mode, ignoring cgroup memory limit: %m");
                 return mem;
+        }
+        if (r > 0) {
+                r = cg_get_attribute("memory", root, "memory.max", &value);
+                if (r < 0) {
+                        log_debug_errno(r, "Failed to read memory.max cgroup attribute, ignoring cgroup memory limit: %m");
+                        return mem;
+                }
+
+                if (streq(value, "max"))
+                        return mem;
+        } else {
+                r = cg_get_attribute("memory", root, "memory.limit_in_bytes", &value);
+                if (r < 0) {
+                        log_debug_errno(r, "Failed to read memory.limit_in_bytes cgroup attribute, ignoring cgroup memory limit: %m");
+                        return mem;
+                }
+        }
 
-        if (safe_atou64(value, &lim) < 0)
+        r = safe_atou64(value, &lim);
+        if (r < 0) {
+                log_debug_errno(r, "Failed to parse cgroup memory limit '%s', ignoring: %m", value);
+                return mem;
+        }
+        if (lim == UINT64_MAX)
                 return mem;
 
         /* Make sure the limit is a multiple of our own page size */
@@ -465,6 +493,7 @@ uint64_t system_tasks_max(void) {
 
         uint64_t a = TASKS_MAX, b = TASKS_MAX;
         _cleanup_free_ char *root = NULL;
+        int r;
 
         /* Determine the maximum number of tasks that may run on this system. We check three sources to determine this
          * limit:
@@ -475,13 +504,24 @@ uint64_t system_tasks_max(void) {
          *
          * And then pick the smallest of the three */
 
-        (void) procfs_tasks_get_limit(&a);
+        r = procfs_tasks_get_limit(&a);
+        if (r < 0)
+                log_debug_errno(r, "Failed to read maximum number of tasks from /proc, ignoring: %m");
 
-        if (cg_get_root_path(&root) >= 0) {
+        r = cg_get_root_path(&root);
+        if (r < 0)
+                log_debug_errno(r, "Failed to determine cgroup root path, ignoring: %m");
+        else {
                 _cleanup_free_ char *value = NULL;
 
-                if (cg_get_attribute("pids", root, "pids.max", &value) >= 0)
-                        (void) safe_atou64(value, &b);
+                r = cg_get_attribute("pids", root, "pids.max", &value);
+                if (r < 0)
+                        log_debug_errno(r, "Failed to read pids.max attribute of cgroup root, ignoring: %m");
+                else if (!streq(value, "max")) {
+                        r = safe_atou64(value, &b);
+                        if (r < 0)
+                                log_debug_errno(r, "Failed to parse pids.max attribute of cgroup root, ignoring: %m");
+                }
         }
 
         return MIN3(TASKS_MAX,
index 03c4937dac78b74ad183a5c26ac4bc0a2d232717..0eb9e4601462817bd0106a180c0454303161c84a 100644 (file)
 #include "log.h"
 #include "string-util.h"
 #include "strv.h"
+#include "terminal-util.h"
 #include "util.h"
 
-static const char conf_file_dirs[] = CONF_PATHS_NULSTR("binfmt.d");
+static bool arg_cat_config = false;
 
 static int delete_rule(const char *rule) {
         _cleanup_free_ char *x = NULL, *fn = NULL;
@@ -63,7 +64,7 @@ static int apply_file(const char *path, bool ignore_enoent) {
 
         assert(path);
 
-        r = search_and_fopen_nulstr(path, "re", NULL, conf_file_dirs, &f);
+        r = search_and_fopen(path, "re", NULL, (const char**) CONF_PATHS_STRV("binfmt.d"), &f);
         if (r < 0) {
                 if (ignore_enoent && r == -ENOENT)
                         return 0;
@@ -102,6 +103,7 @@ static void help(void) {
                "Registers binary formats.\n\n"
                "  -h --help             Show this help\n"
                "     --version          Show package version\n"
+               "     --cat-config       Show configuration files\n"
                , program_invocation_short_name);
 }
 
@@ -109,11 +111,13 @@ static int parse_argv(int argc, char *argv[]) {
 
         enum {
                 ARG_VERSION = 0x100,
+                ARG_CAT_CONFIG,
         };
 
         static const struct option options[] = {
-                { "help",      no_argument,       NULL, 'h'           },
-                { "version",   no_argument,       NULL, ARG_VERSION   },
+                { "help",       no_argument,       NULL, 'h'            },
+                { "version",    no_argument,       NULL, ARG_VERSION    },
+                { "cat-config", no_argument,       NULL, ARG_CAT_CONFIG },
                 {}
         };
 
@@ -133,6 +137,10 @@ static int parse_argv(int argc, char *argv[]) {
                 case ARG_VERSION:
                         return version();
 
+                case ARG_CAT_CONFIG:
+                        arg_cat_config = true;
+                        break;
+
                 case '?':
                         return -EINVAL;
 
@@ -140,6 +148,11 @@ static int parse_argv(int argc, char *argv[]) {
                         assert_not_reached("Unhandled option");
                 }
 
+        if (arg_cat_config && argc > optind) {
+                log_error("Positional arguments are not allowed with --cat-config");
+                return -EINVAL;
+        }
+
         return 1;
 }
 
@@ -170,12 +183,17 @@ int main(int argc, char *argv[]) {
                 _cleanup_strv_free_ char **files = NULL;
                 char **f;
 
-                r = conf_files_list_nulstr(&files, ".conf", NULL, 0, conf_file_dirs);
+                r = conf_files_list_strv(&files, ".conf", NULL, 0, (const char**) CONF_PATHS_STRV("binfmt.d"));
                 if (r < 0) {
                         log_error_errno(r, "Failed to enumerate binfmt.d files: %m");
                         goto finish;
                 }
 
+                if (arg_cat_config) {
+                        r = cat_files(NULL, files, 0);
+                        goto finish;
+                }
+
                 /* Flush out all rules */
                 write_string_file("/proc/sys/fs/binfmt_misc/status", "-1", 0);
 
index f19edfd987428e1e2925351c28d885269d5b6ae8..5c65147caca84ad4ef6135486e6687c2f92777cb 100644 (file)
@@ -914,10 +914,6 @@ static int on_property(const char *interface, const char *name, const char *sign
         return 0;
 }
 
-static const char *strdash(const char *x) {
-        return isempty(x) ? "-" : x;
-}
-
 static int introspect(int argc, char **argv, void *userdata) {
         static const struct hash_ops member_hash_ops = {
                 .hash = member_hash_func,
@@ -1104,15 +1100,15 @@ static int introspect(int argc, char **argv, void *userdata) {
 
                         rv = ellipsized;
                 } else
-                        rv = strdash(m->result);
+                        rv = empty_to_dash(m->result);
 
                 printf("%s%s%-*s%s %-*s %-*s %-*s%s%s%s%s%s%s\n",
                        is_interface ? ansi_highlight() : "",
                        is_interface ? "" : ".",
-                       - !is_interface + (int) name_width, strdash(streq_ptr(m->type, "interface") ? m->interface : m->name),
+                       - !is_interface + (int) name_width, empty_to_dash(streq_ptr(m->type, "interface") ? m->interface : m->name),
                        is_interface ? ansi_normal() : "",
-                       (int) type_width, strdash(m->type),
-                       (int) signature_width, strdash(m->signature),
+                       (int) type_width, empty_to_dash(m->type),
+                       (int) signature_width, empty_to_dash(m->signature),
                        (int) result_width, rv,
                        (m->flags & SD_BUS_VTABLE_DEPRECATED) ? " deprecated" : (m->flags || m->writable ? "" : " -"),
                        (m->flags & SD_BUS_VTABLE_METHOD_NO_REPLY) ? " no-reply" : "",
index 61e0a67b83c5e0060cc9914029fdb463d5a45bb6..7c7ea18b6159c13bb8b10606bbe08a9ca953da53 100644 (file)
@@ -149,7 +149,7 @@ static void show_cg_info(const char *controller, const char *path) {
         if (cg_all_unified() == 0 && controller && !streq(controller, SYSTEMD_CGROUP_CONTROLLER))
                 printf("Controller %s; ", controller);
 
-        printf("Control group %s:\n", isempty(path) ? "/" : path);
+        printf("Control group %s:\n", empty_to_root(path));
         fflush(stdout);
 }
 
index de7ecf54cda902df4f4369996601aec5bcf77324..401c08600ae121e7ffd558a3e1b4d0bf818c65ea 100644 (file)
@@ -529,10 +529,6 @@ static int refresh(const char *root, Hashmap *a, Hashmap *b, unsigned iteration)
         return 0;
 }
 
-static const char *empty_to_slash(const char *p) {
-        return isempty(p) ? "/" : p;
-}
-
 static int group_compare(const void*a, const void *b) {
         const Group *x = *(Group**)a, *y = *(Group**)b;
 
@@ -542,9 +538,9 @@ static int group_compare(const void*a, const void *b) {
                  * recursive summing is off, since that is actually
                  * not accumulative for all children. */
 
-                if (path_startswith(empty_to_slash(y->path), empty_to_slash(x->path)))
+                if (path_startswith(empty_to_root(y->path), empty_to_root(x->path)))
                         return -1;
-                if (path_startswith(empty_to_slash(x->path), empty_to_slash(y->path)))
+                if (path_startswith(empty_to_root(x->path), empty_to_root(y->path)))
                         return 1;
         }
 
@@ -693,7 +689,7 @@ static void display(Hashmap *a) {
 
                 g = array[j];
 
-                path = empty_to_slash(g->path);
+                path = empty_to_root(g->path);
                 ellipsized = ellipsize(path, path_columns, 33);
                 printf("%-*s", path_columns, ellipsized ?: path);
 
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 6ad89843cca5143a37c10d178a79a9938911a1a3..2d4079a7b474defcb7000a7b04aece6e07580587 100644 (file)
@@ -7,7 +7,6 @@
   Copyright 2010 Lennart Poettering
 ***/
 
-
 extern const sd_bus_vtable bus_automount_vtable[];
 
 int bus_automount_set_property(Unit *u, const char *name, sd_bus_message *message, UnitWriteFlags flags, sd_bus_error *error);
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 e0abf384758f6f9af074a708f45d8694d9c20809..977ef22c9481f829225bb379c333ea56280b402b 100644 (file)
 
 BUS_DEFINE_PROPERTY_GET_ENUM(bus_property_get_exec_output, exec_output, ExecOutput);
 static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_exec_input, exec_input, ExecInput);
-
 static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_exec_utmp_mode, exec_utmp_mode, ExecUtmpMode);
 static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_exec_preserve_mode, exec_preserve_mode, ExecPreserveMode);
 static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_exec_keyring_mode, exec_keyring_mode, ExecKeyringMode);
-
-static BUS_DEFINE_PROPERTY_GET_ENUM(bus_property_get_protect_home, protect_home, ProtectHome);
-static BUS_DEFINE_PROPERTY_GET_ENUM(bus_property_get_protect_system, protect_system, ProtectSystem);
+static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_protect_home, protect_home, ProtectHome);
+static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_protect_system, protect_system, ProtectSystem);
+static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_personality, personality, unsigned long);
+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,
@@ -148,60 +153,6 @@ static int property_get_nice(
         return sd_bus_message_append(reply, "i", n);
 }
 
-static int property_get_ioprio(
-                sd_bus *bus,
-                const char *path,
-                const char *interface,
-                const char *property,
-                sd_bus_message *reply,
-                void *userdata,
-                sd_bus_error *error) {
-
-        ExecContext *c = userdata;
-
-        assert(bus);
-        assert(reply);
-        assert(c);
-
-        return sd_bus_message_append(reply, "i", exec_context_get_effective_ioprio(c));
-}
-
-static int property_get_ioprio_class(
-                sd_bus *bus,
-                const char *path,
-                const char *interface,
-                const char *property,
-                sd_bus_message *reply,
-                void *userdata,
-                sd_bus_error *error) {
-
-        ExecContext *c = userdata;
-
-        assert(bus);
-        assert(reply);
-        assert(c);
-
-        return sd_bus_message_append(reply, "i", IOPRIO_PRIO_CLASS(exec_context_get_effective_ioprio(c)));
-}
-
-static int property_get_ioprio_priority(
-                sd_bus *bus,
-                const char *path,
-                const char *interface,
-                const char *property,
-                sd_bus_message *reply,
-                void *userdata,
-                sd_bus_error *error) {
-
-        ExecContext *c = userdata;
-
-        assert(bus);
-        assert(reply);
-        assert(c);
-
-        return sd_bus_message_append(reply, "i", IOPRIO_PRIO_DATA(exec_context_get_effective_ioprio(c)));
-}
-
 static int property_get_cpu_sched_policy(
                 sd_bus *bus,
                 const char *path,
@@ -274,10 +225,7 @@ static int property_get_cpu_affinity(
         assert(reply);
         assert(c);
 
-        if (c->cpuset)
-                return sd_bus_message_append_array(reply, 'y', c->cpuset, CPU_ALLOC_SIZE(c->cpuset_ncpus));
-        else
-                return sd_bus_message_append_array(reply, 'y', NULL, 0);
+        return sd_bus_message_append_array(reply, 'y', c->cpuset, CPU_ALLOC_SIZE(c->cpuset_ncpus));
 }
 
 static int property_get_timer_slack_nsec(
@@ -304,57 +252,6 @@ static int property_get_timer_slack_nsec(
         return sd_bus_message_append(reply, "t", u);
 }
 
-static int property_get_capability_bounding_set(
-                sd_bus *bus,
-                const char *path,
-                const char *interface,
-                const char *property,
-                sd_bus_message *reply,
-                void *userdata,
-                sd_bus_error *error) {
-
-        ExecContext *c = userdata;
-
-        assert(bus);
-        assert(reply);
-        assert(c);
-
-        return sd_bus_message_append(reply, "t", c->capability_bounding_set);
-}
-
-static int property_get_ambient_capabilities(
-                sd_bus *bus,
-                const char *path,
-                const char *interface,
-                const char *property,
-                sd_bus_message *reply,
-                void *userdata,
-                sd_bus_error *error) {
-
-        ExecContext *c = userdata;
-
-        assert(bus);
-        assert(reply);
-        assert(c);
-
-        return sd_bus_message_append(reply, "t", c->capability_ambient_set);
-}
-
-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", "");
-}
-
 static int property_get_syscall_filter(
                 sd_bus *bus,
                 const char *path,
@@ -470,24 +367,6 @@ static int property_get_syscall_archs(
         return 0;
 }
 
-static int property_get_syscall_errno(
-                sd_bus *bus,
-                const char *path,
-                const char *interface,
-                const char *property,
-                sd_bus_message *reply,
-                void *userdata,
-                sd_bus_error *error) {
-
-        ExecContext *c = userdata;
-
-        assert(bus);
-        assert(reply);
-        assert(c);
-
-        return sd_bus_message_append(reply, "i", (int32_t) c->syscall_errno);
-}
-
 static int property_get_selinux_context(
                 sd_bus *bus,
                 const char *path,
@@ -542,24 +421,6 @@ static int property_get_smack_process_label(
         return sd_bus_message_append(reply, "(bs)", c->smack_process_label_ignore, c->smack_process_label);
 }
 
-static int property_get_personality(
-                sd_bus *bus,
-                const char *path,
-                const char *interface,
-                const char *property,
-                sd_bus_message *reply,
-                void *userdata,
-                sd_bus_error *error) {
-
-        ExecContext *c = userdata;
-
-        assert(bus);
-        assert(reply);
-        assert(c);
-
-        return sd_bus_message_append(reply, "s", personality_to_string(c->personality));
-}
-
 static int property_get_address_families(
                 sd_bus *bus,
                 const char *path,
@@ -635,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) {
-
-        ExecContext *c = userdata;
-
-        assert(bus);
-        assert(reply);
-        assert(c);
-
-        return sd_bus_message_append(reply, "i", LOG_PRI(c->syslog_priority));
-}
-
-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) {
-
-        ExecContext *c = userdata;
-
-        assert(bus);
-        assert(reply);
-        assert(c);
-
-        return sd_bus_message_append(reply, "i", LOG_FAC(c->syslog_priority));
-}
-
 static int property_get_stdio_fdname(
                 sd_bus *bus,
                 const char *path,
@@ -895,13 +720,13 @@ const sd_bus_vtable bus_exec_vtable[] = {
         SD_BUS_PROPERTY("SyslogPriority", "i", bus_property_get_int, offsetof(ExecContext, syslog_priority), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("SyslogIdentifier", "s", NULL, offsetof(ExecContext, syslog_identifier), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("SyslogLevelPrefix", "b", bus_property_get_bool, offsetof(ExecContext, syslog_level_prefix), SD_BUS_VTABLE_PROPERTY_CONST),
-        SD_BUS_PROPERTY("SyslogLevel", "i", property_get_syslog_level, 0, SD_BUS_VTABLE_PROPERTY_CONST),
-        SD_BUS_PROPERTY("SyslogFacility", "i", property_get_syslog_facility, 0, SD_BUS_VTABLE_PROPERTY_CONST),
+        SD_BUS_PROPERTY("SyslogLevel", "i", property_get_syslog_level, offsetof(ExecContext, syslog_priority), SD_BUS_VTABLE_PROPERTY_CONST),
+        SD_BUS_PROPERTY("SyslogFacility", "i", property_get_syslog_facility, offsetof(ExecContext, syslog_priority), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("LogLevelMax", "i", bus_property_get_int, offsetof(ExecContext, log_level_max), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("LogExtraFields", "aay", property_get_log_extra_fields, 0, SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("SecureBits", "i", bus_property_get_int, offsetof(ExecContext, secure_bits), SD_BUS_VTABLE_PROPERTY_CONST),
-        SD_BUS_PROPERTY("CapabilityBoundingSet", "t", property_get_capability_bounding_set, 0, SD_BUS_VTABLE_PROPERTY_CONST),
-        SD_BUS_PROPERTY("AmbientCapabilities", "t", property_get_ambient_capabilities, 0, SD_BUS_VTABLE_PROPERTY_CONST),
+        SD_BUS_PROPERTY("CapabilityBoundingSet", "t", NULL, offsetof(ExecContext, capability_bounding_set), SD_BUS_VTABLE_PROPERTY_CONST),
+        SD_BUS_PROPERTY("AmbientCapabilities", "t", NULL, offsetof(ExecContext, capability_ambient_set), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("User", "s", NULL, offsetof(ExecContext, user), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("Group", "s", NULL, offsetof(ExecContext, group), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("DynamicUser", "b", bus_property_get_bool, offsetof(ExecContext, dynamic_user), SD_BUS_VTABLE_PROPERTY_CONST),
@@ -919,8 +744,8 @@ const sd_bus_vtable bus_exec_vtable[] = {
         SD_BUS_PROPERTY("ProtectControlGroups", "b", bus_property_get_bool, offsetof(ExecContext, protect_control_groups), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("PrivateNetwork", "b", bus_property_get_bool, offsetof(ExecContext, private_network), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("PrivateUsers", "b", bus_property_get_bool, offsetof(ExecContext, private_users), SD_BUS_VTABLE_PROPERTY_CONST),
-        SD_BUS_PROPERTY("ProtectHome", "s", bus_property_get_protect_home, offsetof(ExecContext, protect_home), SD_BUS_VTABLE_PROPERTY_CONST),
-        SD_BUS_PROPERTY("ProtectSystem", "s", bus_property_get_protect_system, offsetof(ExecContext, protect_system), SD_BUS_VTABLE_PROPERTY_CONST),
+        SD_BUS_PROPERTY("ProtectHome", "s", property_get_protect_home, offsetof(ExecContext, protect_home), SD_BUS_VTABLE_PROPERTY_CONST),
+        SD_BUS_PROPERTY("ProtectSystem", "s", property_get_protect_system, offsetof(ExecContext, protect_system), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("SameProcessGroup", "b", bus_property_get_bool, offsetof(ExecContext, same_pgrp), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("UtmpIdentifier", "s", NULL, offsetof(ExecContext, utmp_id), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("UtmpMode", "s", property_get_exec_utmp_mode, offsetof(ExecContext, utmp_mode), SD_BUS_VTABLE_PROPERTY_CONST),
@@ -931,8 +756,8 @@ const sd_bus_vtable bus_exec_vtable[] = {
         SD_BUS_PROPERTY("NoNewPrivileges", "b", bus_property_get_bool, offsetof(ExecContext, no_new_privileges), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("SystemCallFilter", "(bas)", property_get_syscall_filter, 0, SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("SystemCallArchitectures", "as", property_get_syscall_archs, 0, SD_BUS_VTABLE_PROPERTY_CONST),
-        SD_BUS_PROPERTY("SystemCallErrorNumber", "i", property_get_syscall_errno, 0, SD_BUS_VTABLE_PROPERTY_CONST),
-        SD_BUS_PROPERTY("Personality", "s", property_get_personality, 0, SD_BUS_VTABLE_PROPERTY_CONST),
+        SD_BUS_PROPERTY("SystemCallErrorNumber", "i", bus_property_get_int, offsetof(ExecContext, syscall_errno), SD_BUS_VTABLE_PROPERTY_CONST),
+        SD_BUS_PROPERTY("Personality", "s", property_get_personality, offsetof(ExecContext, personality), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("LockPersonality", "b", bus_property_get_bool, offsetof(ExecContext, lock_personality), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("RestrictAddressFamilies", "(bas)", property_get_address_families, 0, SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("RuntimeDirectoryPreserve", "s", property_get_exec_preserve_mode, offsetof(ExecContext, runtime_directory_preserve_mode), SD_BUS_VTABLE_PROPERTY_CONST),
@@ -1218,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);
@@ -2023,9 +1848,7 @@ int bus_exec_context_set_transient_property(
                                 if (!e)
                                         return -ENOMEM;
 
-                                strv_free(c->environment);
-                                c->environment = e;
-
+                                strv_free_and_replace(c->environment, e);
                                 unit_write_settingf(u, flags, name, "Environment=%s", joined);
                         }
                 }
@@ -2059,9 +1882,7 @@ int bus_exec_context_set_transient_property(
                                 if (!e)
                                         return -ENOMEM;
 
-                                strv_free(c->unset_environment);
-                                c->unset_environment = e;
-
+                                strv_free_and_replace(c->unset_environment, e);
                                 unit_write_settingf(u, flags, name, "UnsetEnvironment=%s", joined);
                         }
                 }
@@ -2270,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)) {
@@ -2444,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;
+                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 (!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 de6aaba22981136b0a898478ce41abe38c7350d2..13d7bd476f8edb619f15f48f4b536c4bdad1260c 100644 (file)
@@ -46,35 +46,14 @@ static UnitFileFlags unit_file_bools_to_flags(bool runtime, bool force) {
                (force   ? UNIT_FILE_FORCE   : 0);
 }
 
-static int property_get_version(
-                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", PACKAGE_VERSION);
-}
-
-static int property_get_features(
-                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", SYSTEMD_FEATURES);
-}
+static BUS_DEFINE_PROPERTY_GET_GLOBAL(property_get_version, "s", PACKAGE_VERSION);
+static BUS_DEFINE_PROPERTY_GET_GLOBAL(property_get_features, "s", SYSTEMD_FEATURES);
+static BUS_DEFINE_PROPERTY_GET_GLOBAL(property_get_architecture, "s", architecture_to_string(uname_architecture()));
+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,
@@ -99,22 +78,7 @@ static int property_get_virtualization(
 
         return sd_bus_message_append(
                         reply, "s",
-                        v == VIRTUALIZATION_NONE ? "" : virtualization_to_string(v));
-}
-
-static int property_get_architecture(
-                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", architecture_to_string(uname_architecture()));
+                        v == VIRTUALIZATION_NONE ? NULL : virtualization_to_string(v));
 }
 
 static int property_get_tainted(
@@ -140,21 +104,6 @@ static int property_get_tainted(
         return sd_bus_message_append(reply, "s", s);
 }
 
-static int property_get_log_target(
-                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", log_target_to_string(log_get_target()));
-}
-
 static int property_set_log_target(
                 sd_bus *bus,
                 const char *path,
@@ -224,60 +173,6 @@ static int property_set_log_level(
         return r;
 }
 
-static int property_get_n_names(
-                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, "u", (uint32_t) hashmap_size(m->units));
-}
-
-static int property_get_n_failed_units(
-                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, "u", (uint32_t) set_size(m->failed_units));
-}
-
-static int property_get_n_jobs(
-                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, "u", (uint32_t) hashmap_size(m->jobs));
-}
-
 static int property_get_progress(
                 sd_bus *bus,
                 const char *path,
@@ -302,7 +197,7 @@ static int property_get_progress(
         return sd_bus_message_append(reply, "d", d);
 }
 
-static int property_get_system_state(
+static int property_get_show_status(
                 sd_bus *bus,
                 const char *path,
                 const char *interface,
@@ -312,12 +207,14 @@ static int property_get_system_state(
                 sd_bus_error *error) {
 
         Manager *m = userdata;
+        int b;
 
         assert(bus);
         assert(reply);
         assert(m);
 
-        return sd_bus_message_append(reply, "s", manager_state_to_string(manager_state(m)));
+        b = m->show_status > 0;
+        return sd_bus_message_append_basic(reply, 'b', &b);
 }
 
 static int property_set_runtime_watchdog(
@@ -344,21 +241,6 @@ static int property_set_runtime_watchdog(
         return watchdog_set_timeout(t);
 }
 
-static int property_get_timer_slack_nsec(
-                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, "t", (uint64_t) prctl(PR_GET_TIMERSLACK));
-}
-
 static int bus_get_unit_by_name(Manager *m, sd_bus_message *message, const char *name, Unit **ret_unit, sd_bus_error *error) {
         Unit *u;
         int r;
@@ -1321,7 +1203,7 @@ static int method_unsubscribe(sd_bus_message *message, void *userdata, sd_bus_er
         return sd_bus_reply_method_return(message, NULL);
 }
 
-static int method_dump(sd_bus_message *message, void *userdata, sd_bus_error *error) {
+static int dump_impl(sd_bus_message *message, void *userdata, sd_bus_error *error, int (*reply)(sd_bus_message *, char *)) {
         _cleanup_free_ char *dump = NULL;
         Manager *m = userdata;
         int r;
@@ -1339,9 +1221,31 @@ static int method_dump(sd_bus_message *message, void *userdata, sd_bus_error *er
         if (r < 0)
                 return r;
 
+        return reply(message, dump);
+}
+
+static int reply_dump(sd_bus_message *message, char *dump) {
         return sd_bus_reply_method_return(message, "s", dump);
 }
 
+static int method_dump(sd_bus_message *message, void *userdata, sd_bus_error *error) {
+        return dump_impl(message, userdata, error, reply_dump);
+}
+
+static int reply_dump_by_fd(sd_bus_message *message, char *dump) {
+        _cleanup_close_ int fd = -1;
+
+        fd = acquire_data_fd(dump, strlen(dump), 0);
+        if (fd < 0)
+                return fd;
+
+        return sd_bus_reply_method_return(message, "h", fd);
+}
+
+static int method_dump_by_fd(sd_bus_message *message, void *userdata, sd_bus_error *error) {
+        return dump_impl(message, userdata, error, reply_dump_by_fd);
+}
+
 static int method_refuse_snapshot(sd_bus_message *message, void *userdata, sd_bus_error *error) {
         return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Support for snapshots has been removed.");
 }
@@ -2497,15 +2401,15 @@ const sd_bus_vtable bus_manager_vtable[] = {
         BUS_PROPERTY_DUAL_TIMESTAMP("UnitsLoadFinishTimestamp", offsetof(Manager, timestamps[MANAGER_TIMESTAMP_UNITS_LOAD_FINISH]), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_WRITABLE_PROPERTY("LogLevel", "s", property_get_log_level, property_set_log_level, 0, 0),
         SD_BUS_WRITABLE_PROPERTY("LogTarget", "s", property_get_log_target, property_set_log_target, 0, 0),
-        SD_BUS_PROPERTY("NNames", "u", property_get_n_names, 0, 0),
-        SD_BUS_PROPERTY("NFailedUnits", "u", property_get_n_failed_units, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
-        SD_BUS_PROPERTY("NJobs", "u", property_get_n_jobs, 0, 0),
+        SD_BUS_PROPERTY("NNames", "u", property_get_hashmap_size, offsetof(Manager, units), 0),
+        SD_BUS_PROPERTY("NFailedUnits", "u", property_get_set_size, offsetof(Manager, failed_units), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
+        SD_BUS_PROPERTY("NJobs", "u", property_get_hashmap_size, offsetof(Manager, jobs), 0),
         SD_BUS_PROPERTY("NInstalledJobs", "u", bus_property_get_unsigned, offsetof(Manager, n_installed_jobs), 0),
         SD_BUS_PROPERTY("NFailedJobs", "u", bus_property_get_unsigned, offsetof(Manager, n_failed_jobs), 0),
         SD_BUS_PROPERTY("Progress", "d", property_get_progress, 0, 0),
         SD_BUS_PROPERTY("Environment", "as", NULL, offsetof(Manager, environment), 0),
         SD_BUS_PROPERTY("ConfirmSpawn", "b", bus_property_get_bool, offsetof(Manager, confirm_spawn), SD_BUS_VTABLE_PROPERTY_CONST),
-        SD_BUS_PROPERTY("ShowStatus", "b", bus_property_get_bool, offsetof(Manager, show_status), SD_BUS_VTABLE_PROPERTY_CONST),
+        SD_BUS_PROPERTY("ShowStatus", "b", property_get_show_status, 0, 0),
         SD_BUS_PROPERTY("UnitPath", "as", NULL, offsetof(Manager, lookup_paths.search_path), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("DefaultStandardOutput", "s", bus_property_get_exec_output, offsetof(Manager, default_std_output), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("DefaultStandardError", "s", bus_property_get_exec_output, offsetof(Manager, default_std_output), SD_BUS_VTABLE_PROPERTY_CONST),
@@ -2598,6 +2502,7 @@ const sd_bus_vtable bus_manager_vtable[] = {
         SD_BUS_METHOD("Subscribe", NULL, NULL, method_subscribe, SD_BUS_VTABLE_UNPRIVILEGED),
         SD_BUS_METHOD("Unsubscribe", NULL, NULL, method_unsubscribe, SD_BUS_VTABLE_UNPRIVILEGED),
         SD_BUS_METHOD("Dump", NULL, "s", method_dump, SD_BUS_VTABLE_UNPRIVILEGED),
+        SD_BUS_METHOD("DumpByFileDescriptor", NULL, "h", method_dump_by_fd, SD_BUS_VTABLE_UNPRIVILEGED),
         SD_BUS_METHOD("CreateSnapshot", "sb", "o", method_refuse_snapshot, SD_BUS_VTABLE_UNPRIVILEGED|SD_BUS_VTABLE_HIDDEN),
         SD_BUS_METHOD("RemoveSnapshot", "s", NULL, method_refuse_snapshot, SD_BUS_VTABLE_UNPRIVILEGED|SD_BUS_VTABLE_HIDDEN),
         SD_BUS_METHOD("Reload", NULL, NULL, method_reload, SD_BUS_VTABLE_UNPRIVILEGED),
index 36582857c76cd95a9361341f03f465b92139a3df..d9b900abadc901f8eee53054eeb26d7f0394390c 100644 (file)
 #include "string-util.h"
 #include "unit.h"
 
-static int property_get_what(
-                sd_bus *bus,
-                const char *path,
-                const char *interface,
-                const char *property,
-                sd_bus_message *reply,
-                void *userdata,
-                sd_bus_error *error) {
-
-        Mount *m = userdata;
-        const char *d = NULL;
-
-        assert(bus);
-        assert(reply);
-        assert(m);
-
+static const char *mount_get_what(const Mount *m) {
         if (m->from_proc_self_mountinfo && m->parameters_proc_self_mountinfo.what)
-                d = m->parameters_proc_self_mountinfo.what;
-        else if (m->from_fragment && m->parameters_fragment.what)
-                d = m->parameters_fragment.what;
-
-        return sd_bus_message_append(reply, "s", d);
+                return m->parameters_proc_self_mountinfo.what;
+        if (m->from_fragment && m->parameters_fragment.what)
+                return m->parameters_fragment.what;
+        return NULL;
 }
 
-static int property_get_options(
-                sd_bus *bus,
-                const char *path,
-                const char *interface,
-                const char *property,
-                sd_bus_message *reply,
-                void *userdata,
-                sd_bus_error *error) {
-
-        Mount *m = userdata;
-        const char *d = NULL;
-
-        assert(bus);
-        assert(reply);
-        assert(m);
-
+static const char *mount_get_options(const Mount *m) {
         if (m->from_proc_self_mountinfo && m->parameters_proc_self_mountinfo.options)
-                d = m->parameters_proc_self_mountinfo.options;
-        else if (m->from_fragment && m->parameters_fragment.options)
-                d = m->parameters_fragment.options;
-
-        return sd_bus_message_append(reply, "s", d);
+                return m->parameters_proc_self_mountinfo.options;
+        if (m->from_fragment && m->parameters_fragment.options)
+                return m->parameters_fragment.options;
+        return NULL;
 }
 
-static int property_get_type(
-                sd_bus *bus,
-                const char *path,
-                const char *interface,
-                const char *property,
-                sd_bus_message *reply,
-                void *userdata,
-                sd_bus_error *error) {
-
-        const char *fstype = NULL;
-        Mount *m = userdata;
-
-        assert(bus);
-        assert(reply);
-        assert(m);
-
+static const char *mount_get_fstype(const Mount *m) {
         if (m->from_proc_self_mountinfo && m->parameters_proc_self_mountinfo.fstype)
-                fstype = m->parameters_proc_self_mountinfo.fstype;
+                return m->parameters_proc_self_mountinfo.fstype;
         else if (m->from_fragment && m->parameters_fragment.fstype)
-                fstype = m->parameters_fragment.fstype;
-
-        return sd_bus_message_append(reply, "s", fstype);
+                return m->parameters_fragment.fstype;
+        return NULL;
 }
 
+static BUS_DEFINE_PROPERTY_GET(property_get_what, "s", Mount, mount_get_what);
+static BUS_DEFINE_PROPERTY_GET(property_get_options, "s", Mount, mount_get_options);
+static BUS_DEFINE_PROPERTY_GET(property_get_type, "s", Mount, mount_get_fstype);
 static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_result, mount_result, MountResult);
 
 const sd_bus_vtable bus_mount_vtable[] = {
@@ -102,8 +57,8 @@ const sd_bus_vtable bus_mount_vtable[] = {
         SD_BUS_PROPERTY("LazyUnmount", "b", bus_property_get_bool, offsetof(Mount, lazy_unmount), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("ForceUnmount", "b", bus_property_get_bool, offsetof(Mount, force_unmount), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("Result", "s", property_get_result, offsetof(Mount, result), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
-        SD_BUS_PROPERTY("UID", "u", NULL, offsetof(Unit, ref_uid), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
-        SD_BUS_PROPERTY("GID", "u", NULL, offsetof(Unit, ref_gid), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
+        SD_BUS_PROPERTY("UID", "u", bus_property_get_uid, offsetof(Unit, ref_uid), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
+        SD_BUS_PROPERTY("GID", "u", bus_property_get_gid, offsetof(Unit, ref_gid), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
         BUS_EXEC_COMMAND_VTABLE("ExecMount", offsetof(Mount, exec_command[MOUNT_EXEC_MOUNT]), SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION),
         BUS_EXEC_COMMAND_VTABLE("ExecUnmount", offsetof(Mount, exec_command[MOUNT_EXEC_UNMOUNT]), SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION),
         BUS_EXEC_COMMAND_VTABLE("ExecRemount", offsetof(Mount, exec_command[MOUNT_EXEC_REMOUNT]), SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION),
index e59093e4154ce6beffbab9153d45f8f31ee130ed..fec67d595f05cad24c2b79027c1fb98bcd15d646 100644 (file)
@@ -47,29 +47,9 @@ static int property_get_paths(
         return sd_bus_message_close_container(reply);
 }
 
-static int property_get_unit(
-                sd_bus *bus,
-                const char *path,
-                const char *interface,
-                const char *property,
-                sd_bus_message *reply,
-                void *userdata,
-                sd_bus_error *error) {
-
-        Unit *p = userdata, *trigger;
-
-        assert(bus);
-        assert(reply);
-        assert(p);
-
-        trigger = UNIT_TRIGGER(p);
-
-        return sd_bus_message_append(reply, "s", trigger ? trigger->id : "");
-}
-
 const sd_bus_vtable bus_path_vtable[] = {
         SD_BUS_VTABLE_START(0),
-        SD_BUS_PROPERTY("Unit", "s", property_get_unit, 0, SD_BUS_VTABLE_PROPERTY_CONST),
+        SD_BUS_PROPERTY("Unit", "s", bus_property_get_triggered_unit, 0, SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("Paths", "a(ss)", property_get_paths, 0, SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("MakeDirectory", "b", bus_property_get_bool, offsetof(Path, make_directory), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("DirectoryMode", "u", bus_property_get_mode, offsetof(Path, directory_mode), SD_BUS_VTABLE_PROPERTY_CONST),
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 3815992ba7f45bb196508714cf55963da6e39aa4..92a86c9c89337485725374f21a87ec809e749fa3 100644 (file)
@@ -123,12 +123,12 @@ const sd_bus_vtable bus_service_vtable[] = {
         SD_BUS_PROPERTY("FileDescriptorStoreMax", "u", bus_property_get_unsigned, offsetof(Service, n_fd_store_max), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("NFileDescriptorStore", "u", bus_property_get_unsigned, offsetof(Service, n_fd_store), 0),
         SD_BUS_PROPERTY("StatusText", "s", NULL, offsetof(Service, status_text), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
-        SD_BUS_PROPERTY("StatusErrno", "i", NULL, offsetof(Service, status_errno), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
+        SD_BUS_PROPERTY("StatusErrno", "i", bus_property_get_int, offsetof(Service, status_errno), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
         SD_BUS_PROPERTY("Result", "s", property_get_result, offsetof(Service, result), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
         SD_BUS_PROPERTY("USBFunctionDescriptors", "s", NULL, offsetof(Service, usb_function_descriptors), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
         SD_BUS_PROPERTY("USBFunctionStrings", "s", NULL, offsetof(Service, usb_function_strings), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
-        SD_BUS_PROPERTY("UID", "u", NULL, offsetof(Unit, ref_uid), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
-        SD_BUS_PROPERTY("GID", "u", NULL, offsetof(Unit, ref_gid), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
+        SD_BUS_PROPERTY("UID", "u", bus_property_get_uid, offsetof(Unit, ref_uid), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
+        SD_BUS_PROPERTY("GID", "u", bus_property_get_gid, offsetof(Unit, ref_gid), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
         SD_BUS_PROPERTY("NRestarts", "u", bus_property_get_unsigned, offsetof(Service, n_restarts), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
 
         BUS_EXEC_STATUS_VTABLE("ExecMain", offsetof(Service, main_exec_status), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
index 89bc5c0a1bd737397f8eb6eeba65258b905a293f..893e3d383928d4f48903815febe89fdf545b705f 100644 (file)
@@ -23,6 +23,7 @@
 
 static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_result, socket_result, SocketResult);
 static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_bind_ipv6_only, socket_address_bind_ipv6_only, SocketAddressBindIPv6Only);
+static BUS_DEFINE_PROPERTY_GET(property_get_fdname, "s", Socket, socket_fdname);
 
 static int property_get_listen(
                 sd_bus *bus,
@@ -78,24 +79,6 @@ static int property_get_listen(
         return sd_bus_message_close_container(reply);
 }
 
-static int property_get_fdname(
-                sd_bus *bus,
-                const char *path,
-                const char *interface,
-                const char *property,
-                sd_bus_message *reply,
-                void *userdata,
-                sd_bus_error *error) {
-
-        Socket *s = SOCKET(userdata);
-
-        assert(bus);
-        assert(reply);
-        assert(s);
-
-        return sd_bus_message_append(reply, "s", socket_fdname(s));
-}
-
 const sd_bus_vtable bus_socket_vtable[] = {
         SD_BUS_VTABLE_START(0),
         SD_BUS_PROPERTY("BindIPv6Only", "s", property_get_bind_ipv6_only, offsetof(Socket, bind_ipv6_only), SD_BUS_VTABLE_PROPERTY_CONST),
@@ -146,8 +129,8 @@ const sd_bus_vtable bus_socket_vtable[] = {
         SD_BUS_PROPERTY("SocketProtocol", "i", bus_property_get_int, offsetof(Socket, socket_protocol), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("TriggerLimitIntervalUSec", "t", bus_property_get_usec, offsetof(Socket, trigger_limit.interval), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("TriggerLimitBurst", "u", bus_property_get_unsigned, offsetof(Socket, trigger_limit.burst), SD_BUS_VTABLE_PROPERTY_CONST),
-        SD_BUS_PROPERTY("UID", "u", NULL, offsetof(Unit, ref_uid), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
-        SD_BUS_PROPERTY("GID", "u", NULL, offsetof(Unit, ref_gid), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
+        SD_BUS_PROPERTY("UID", "u", bus_property_get_uid, offsetof(Unit, ref_uid), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
+        SD_BUS_PROPERTY("GID", "u", bus_property_get_gid, offsetof(Unit, ref_gid), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
         BUS_EXEC_COMMAND_LIST_VTABLE("ExecStartPre", offsetof(Socket, exec_command[SOCKET_EXEC_START_PRE]), SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION),
         BUS_EXEC_COMMAND_LIST_VTABLE("ExecStartPost", offsetof(Socket, exec_command[SOCKET_EXEC_START_POST]), SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION),
         BUS_EXEC_COMMAND_LIST_VTABLE("ExecStopPre", offsetof(Socket, exec_command[SOCKET_EXEC_STOP_PRE]), SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION),
index 07854f163778327f9fd92dab4014b81a4e77613f..f44220577753a9c578f8b45ec0ab0a5ce2e3225a 100644 (file)
 #include "swap.h"
 #include "unit.h"
 
-static int property_get_priority(
-                sd_bus *bus,
-                const char *path,
-                const char *interface,
-                const char *property,
-                sd_bus_message *reply,
-                void *userdata,
-                sd_bus_error *error) {
-
-        Swap *s = SWAP(userdata);
-        int p;
-
-        assert(bus);
-        assert(reply);
-        assert(s);
-
+static int swap_get_priority(Swap *s) {
         if (s->from_proc_swaps)
-                p = s->parameters_proc_swaps.priority;
-        else if (s->from_fragment)
-                p = s->parameters_fragment.priority;
-        else
-                p = -1;
-
-        return sd_bus_message_append(reply, "i", p);
+                return s->parameters_proc_swaps.priority;
+        if (s->from_fragment)
+                return s->parameters_fragment.priority;
+        return -1;
 }
 
-static int property_get_options(
-                sd_bus *bus,
-                const char *path,
-                const char *interface,
-                const char *property,
-                sd_bus_message *reply,
-                void *userdata,
-                sd_bus_error *error) {
-
-        Swap *s = SWAP(userdata);
-        const char *options = NULL;
-
-        assert(bus);
-        assert(reply);
-        assert(s);
-
+static const char *swap_get_options(Swap *s) {
         if (s->from_fragment)
-                options = s->parameters_fragment.options;
-
-        return sd_bus_message_append(reply, "s", options);
+                return s->parameters_fragment.options;
+        return NULL;
 }
 
+static BUS_DEFINE_PROPERTY_GET(property_get_priority, "i", Swap, swap_get_priority);
+static BUS_DEFINE_PROPERTY_GET(property_get_options, "s", Swap, swap_get_options);
 static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_result, swap_result, SwapResult);
 
 const sd_bus_vtable bus_swap_vtable[] = {
@@ -72,8 +40,8 @@ const sd_bus_vtable bus_swap_vtable[] = {
         SD_BUS_PROPERTY("TimeoutUSec", "t", bus_property_get_usec, offsetof(Swap, timeout_usec), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("ControlPID", "u", bus_property_get_pid, offsetof(Swap, control_pid), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
         SD_BUS_PROPERTY("Result", "s", property_get_result, offsetof(Swap, result), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
-        SD_BUS_PROPERTY("UID", "u", NULL, offsetof(Unit, ref_uid), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
-        SD_BUS_PROPERTY("GID", "u", NULL, offsetof(Unit, ref_gid), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
+        SD_BUS_PROPERTY("UID", "u", bus_property_get_uid, offsetof(Unit, ref_uid), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
+        SD_BUS_PROPERTY("GID", "u", bus_property_get_gid, offsetof(Unit, ref_gid), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
         BUS_EXEC_COMMAND_VTABLE("ExecActivate", offsetof(Swap, exec_command[SWAP_EXEC_ACTIVATE]), SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION),
         BUS_EXEC_COMMAND_VTABLE("ExecDeactivate", offsetof(Swap, exec_command[SWAP_EXEC_DEACTIVATE]), SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION),
         SD_BUS_VTABLE_END
index de34febb63be75e895799a4fc4facc28c408425d..eef060ff0f6019a11d283682522faeea6c7e91d2 100644 (file)
@@ -103,26 +103,6 @@ static int property_get_calendar_timers(
         return sd_bus_message_close_container(reply);
 }
 
-static int property_get_unit(
-                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, *trigger;
-
-        assert(bus);
-        assert(reply);
-        assert(u);
-
-        trigger = UNIT_TRIGGER(u);
-
-        return sd_bus_message_append(reply, "s", trigger ? trigger->id : "");
-}
-
 static int property_get_next_elapse_monotonic(
                 sd_bus *bus,
                 const char *path,
@@ -145,7 +125,7 @@ static int property_get_next_elapse_monotonic(
 
 const sd_bus_vtable bus_timer_vtable[] = {
         SD_BUS_VTABLE_START(0),
-        SD_BUS_PROPERTY("Unit", "s", property_get_unit, 0, SD_BUS_VTABLE_PROPERTY_CONST),
+        SD_BUS_PROPERTY("Unit", "s", bus_property_get_triggered_unit, 0, SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("TimersMonotonic", "a(stt)", property_get_monotonic_timers, 0, SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION),
         SD_BUS_PROPERTY("TimersCalendar", "a(sst)", property_get_calendar_timers, 0, SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION),
         SD_BUS_PROPERTY("NextElapseUSecRealtime", "t", bus_property_get_usec, offsetof(Timer, next_elapse_realtime), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
index 4d168b240d658bbf355c3984b997f946e15e816a..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);
 static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_emergency_action, emergency_action, EmergencyAction);
+static BUS_DEFINE_PROPERTY_GET(property_get_description, "s", Unit, unit_description);
+static BUS_DEFINE_PROPERTY_GET2(property_get_active_state, "s", Unit, unit_active_state, unit_active_state_to_string);
+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,
@@ -43,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;
@@ -81,7 +103,7 @@ static int property_get_following(
         assert(u);
 
         f = unit_following(u);
-        return sd_bus_message_append(reply, "s", f ? f->id : "");
+        return sd_bus_message_append(reply, "s", f ? f->id : NULL);
 }
 
 static int property_get_dependencies(
@@ -93,7 +115,7 @@ static int property_get_dependencies(
                 void *userdata,
                 sd_bus_error *error) {
 
-        Hashmap *h = *(Hashmap**) userdata;
+        Hashmap **h = userdata;
         Iterator j;
         Unit *u;
         void *v;
@@ -101,12 +123,13 @@ static int property_get_dependencies(
 
         assert(bus);
         assert(reply);
+        assert(h);
 
         r = sd_bus_message_open_container(reply, 'a', "s");
         if (r < 0)
                 return r;
 
-        HASHMAP_FOREACH_KEY(v, u, h, j) {
+        HASHMAP_FOREACH_KEY(v, u, *h, j) {
                 r = sd_bus_message_append(reply, "s", u->id);
                 if (r < 0)
                         return r;
@@ -115,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,
@@ -140,7 +147,7 @@ static int property_get_requires_mounts_for(
                 void *userdata,
                 sd_bus_error *error) {
 
-        Hashmap *h = *(Hashmap**) userdata;
+        Hashmap **h = userdata;
         const char *p;
         Iterator j;
         void *v;
@@ -148,12 +155,13 @@ static int property_get_requires_mounts_for(
 
         assert(bus);
         assert(reply);
+        assert(h);
 
         r = sd_bus_message_open_container(reply, 'a', "s");
         if (r < 0)
                 return r;
 
-        HASHMAP_FOREACH_KEY(v, p, h, j) {
+        HASHMAP_FOREACH_KEY(v, p, *h, j) {
                 r = sd_bus_message_append(reply, "s", p);
                 if (r < 0)
                         return r;
@@ -162,60 +170,6 @@ static int property_get_requires_mounts_for(
         return sd_bus_message_close_container(reply);
 }
 
-static int property_get_description(
-                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, "s", unit_description(u));
-}
-
-static int property_get_active_state(
-                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, "s", unit_active_state_to_string(unit_active_state(u)));
-}
-
-static int property_get_sub_state(
-                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, "s", unit_sub_state_to_string(u));
-}
-
 static int property_get_unit_file_preset(
                 sd_bus *bus,
                 const char *path,
@@ -235,100 +189,10 @@ static int property_get_unit_file_preset(
         r = unit_get_unit_file_preset(u);
 
         return sd_bus_message_append(reply, "s",
-                                     r < 0 ? "":
+                                     r < 0 ? NULL:
                                      r > 0 ? "enabled" : "disabled");
 }
 
-static int property_get_unit_file_state(
-                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, "s", unit_file_state_to_string(unit_get_unit_file_state(u)));
-}
-
-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_reload(
-                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_reload(u));
-}
-
-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,
@@ -339,38 +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);
-}
-
-static int property_get_need_daemon_reload(
-                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_need_daemon_reload(u));
+        return sd_bus_message_append(reply, "(uo)", (*j)->id, p);
 }
 
 static int property_get_conditions(
@@ -425,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);
 }
@@ -722,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),
@@ -764,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),
@@ -783,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),
@@ -808,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
@@ -918,7 +765,7 @@ static int property_get_cgroup(
                 sd_bus_error *error) {
 
         Unit *u = userdata;
-        const char *t;
+        const char *t = NULL;
 
         assert(bus);
         assert(reply);
@@ -931,9 +778,7 @@ static int property_get_cgroup(
          * other cases we report as-is. */
 
         if (u->cgroup_path)
-                t = isempty(u->cgroup_path) ? "/" : u->cgroup_path;
-        else
-                t = "";
+                t = empty_to_root(u->cgroup_path);
 
         return sd_bus_message_append(reply, "s", t);
 }
@@ -1030,7 +875,7 @@ static int append_cgroup(sd_bus_message *reply, const char *p, Set *pids) {
 
 int bus_unit_method_get_processes(sd_bus_message *message, void *userdata, sd_bus_error *error) {
         _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
-        _cleanup_(set_freep) Set *pids = NULL;
+        _cleanup_set_free_ Set *pids = NULL;
         Unit *u = userdata;
         pid_t pid;
         int r;
@@ -1117,7 +962,7 @@ static int property_get_ip_counter(
 int bus_unit_method_attach_processes(sd_bus_message *message, void *userdata, sd_bus_error *error) {
 
         _cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL;
-        _cleanup_(set_freep) Set *pids = NULL;
+        _cleanup_set_free_ Set *pids = NULL;
         Unit *u = userdata;
         const char *path;
         int r;
index 2aa682f10310df7961c185ac1b61a3c22ba602cf..15a3169bef69b0f4b804747008ed9b5c90172f8f 100644 (file)
 #include "user-util.h"
 #include "unit.h"
 
+int bus_property_get_triggered_unit(
+                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, *trigger;
+
+        assert(bus);
+        assert(reply);
+        assert(u);
+
+        trigger = UNIT_TRIGGER(u);
+
+        return sd_bus_message_append(reply, "s", trigger ? trigger->id : NULL);
+}
+
 BUS_DEFINE_SET_TRANSIENT(mode_t, "u", uint32_t, mode_t, "%040o");
 BUS_DEFINE_SET_TRANSIENT(unsigned, "u", uint32_t, unsigned, "%" PRIu32);
 BUS_DEFINE_SET_TRANSIENT_STRING_WITH_CHECK(user, valid_user_group_name_or_id);
index 18c40f9148ce86eb7fe7ea522b95754ade21f8c2..b1f7b69d7960536b3b4501b3bda1cbd08d82b928 100644 (file)
@@ -10,6 +10,8 @@
 #include "sd-bus.h"
 #include "unit.h"
 
+int bus_property_get_triggered_unit(sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *reply, void *userdata, sd_bus_error *error);
+
 #define BUS_DEFINE_SET_TRANSIENT(function, bus_type, type, cast_type, fmt) \
         int bus_set_transient_##function(                               \
                         Unit *u,                                        \
index 47492835ee8e729506893717c9a3d02c9042eca0..4df898f963b6d9500637f5e6cedc49ebcd6664f9 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"
@@ -229,7 +230,6 @@ static int mac_selinux_filter(sd_bus_message *message, void *userdata, sd_bus_er
         path = sd_bus_message_get_path(message);
 
         if (object_path_startswith("/org/freedesktop/systemd1", path)) {
-
                 r = mac_selinux_access_check(message, verb, error);
                 if (r < 0)
                         return r;
@@ -257,7 +257,6 @@ static int mac_selinux_filter(sd_bus_message *message, void *userdata, sd_bus_er
                 else
                         manager_load_unit_from_dbus_path(m, path, NULL, &u);
         }
-
         if (!u)
                 return 0;
 
index 565410fd36149a41a2971d6116eaa1abd1c2d152..a775e8bb957d1addb58729aaae473009216c8e6e 100644 (file)
@@ -704,7 +704,7 @@ static Unit *device_following(Unit *u) {
 
 static int device_following_set(Unit *u, Set **_set) {
         Device *d = DEVICE(u), *other;
-        Set *set;
+        _cleanup_set_free_ Set *set = NULL;
         int r;
 
         assert(d);
@@ -722,21 +722,17 @@ static int device_following_set(Unit *u, Set **_set) {
         LIST_FOREACH_AFTER(same_sysfs, other, d) {
                 r = set_put(set, other);
                 if (r < 0)
-                        goto fail;
+                        return r;
         }
 
         LIST_FOREACH_BEFORE(same_sysfs, other, d) {
                 r = set_put(set, other);
                 if (r < 0)
-                        goto fail;
+                        return r;
         }
 
-        *_set = set;
+        *_set = TAKE_PTR(set);
         return 1;
-
-fail:
-        set_free(set);
-        return r;
 }
 
 static void device_shutdown(Manager *m) {
@@ -849,7 +845,7 @@ static int device_dispatch_io(sd_event_source *source, int fd, uint32_t revents,
         if (revents != EPOLLIN) {
                 static RATELIMIT_DEFINE(limit, 10*USEC_PER_SEC, 5);
 
-                if (ratelimit_test(&limit))
+                if (ratelimit_below(&limit))
                         log_warning("Failed to get udev event");
                 if (!(revents & EPOLLIN))
                         return 0;
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 87909c07e94ae3c5db7e5c872e8fd2cfed55bf8d..939bc12b565000177f87378df0b8f8a0750be7de 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"
@@ -1287,10 +1288,7 @@ static int setup_pam(
         if (!barrier_place_and_sync(&barrier))
                 log_error("PAM initialization failed");
 
-        strv_free(*env);
-        *env = e;
-
-        return 0;
+        return strv_free_and_replace(*env, e);
 
 fail:
         if (pam_code != PAM_SUCCESS) {
@@ -2091,10 +2089,10 @@ static int setup_exec_directory(
                         }
                 } else {
                         r = mkdir_label(p, context->directories[type].mode);
-                        if (r == -EEXIST)
-                                continue;
-                        if (r < 0)
+                        if (r < 0 && r != -EEXIST)
                                 goto fail;
+                        if (r == -EEXIST && !context->dynamic_user)
+                                continue;
                 }
 
                 /* Don't change the owner of the configuration directory, as in the common case it is not written to by
@@ -2729,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;
@@ -2918,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) {
@@ -3169,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. */
@@ -3379,8 +3366,7 @@ static int exec_child(
                         return log_oom();
                 }
 
-                strv_free(accum_env);
-                accum_env = ee;
+                strv_free_and_replace(accum_env, ee);
         }
 
         final_argv = replace_env_argv(argv, accum_env);
@@ -3578,8 +3564,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]);
@@ -3979,9 +3964,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);
                 }
 
@@ -4493,10 +4478,7 @@ int exec_command_set(ExecCommand *c, const char *path, ...) {
         free(c->path);
         c->path = p;
 
-        strv_free(c->argv);
-        c->argv = l;
-
-        return 0;
+        return strv_free_and_replace(c->argv, l);
 }
 
 int exec_command_append(ExecCommand *c, const char *path, ...) {
index a684e4529ddc528e7badd0301b1418acef74d1fe..eaa1cc312d91c52719fe57f398f9988d7bc92392 100644 (file)
@@ -7,6 +7,7 @@
   Copyright 2016 Daniel Mack
 ***/
 
+#include "conf-parser.h"
 #include "in-addr-util.h"
 #include "list.h"
 
@@ -19,7 +20,7 @@ struct IPAddressAccessItem {
         LIST_FIELDS(IPAddressAccessItem, items);
 };
 
-int config_parse_ip_address_access(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);
+CONFIG_PARSER_PROTOTYPE(config_parse_ip_address_access);
 
 IPAddressAccessItem* ip_address_access_free_all(IPAddressAccessItem *first);
 
index 32f6fc1a50f243583c218800631d31ebf3c38e3a..92abd60c2f1bc02b6dec0d5aa723ddf435366876 100644 (file)
@@ -43,6 +43,7 @@ Job* job_new_raw(Unit *unit) {
         j->manager = unit->manager;
         j->unit = unit;
         j->type = _JOB_TYPE_INVALID;
+        j->reloaded = false;
 
         return j;
 }
@@ -64,7 +65,7 @@ Job* job_new(Unit *unit, JobType type) {
         return j;
 }
 
-void job_free(Job *j) {
+void job_unlink(Job *j) {
         assert(j);
         assert(!j->installed);
         assert(!j->transaction_prev);
@@ -72,16 +73,33 @@ void job_free(Job *j) {
         assert(!j->subject_list);
         assert(!j->object_list);
 
-        if (j->in_run_queue)
+        if (j->in_run_queue) {
                 LIST_REMOVE(run_queue, j->manager->run_queue, j);
+                j->in_run_queue = false;
+        }
 
-        if (j->in_dbus_queue)
+        if (j->in_dbus_queue) {
                 LIST_REMOVE(dbus_queue, j->manager->dbus_job_queue, j);
+                j->in_dbus_queue = false;
+        }
 
-        if (j->in_gc_queue)
+        if (j->in_gc_queue) {
                 LIST_REMOVE(gc_queue, j->manager->gc_job_queue, j);
+                j->in_gc_queue = false;
+        }
 
-        sd_event_source_unref(j->timer_event_source);
+        j->timer_event_source = sd_event_source_unref(j->timer_event_source);
+}
+
+void job_free(Job *j) {
+        assert(j);
+        assert(!j->installed);
+        assert(!j->transaction_prev);
+        assert(!j->transaction_next);
+        assert(!j->subject_list);
+        assert(!j->object_list);
+
+        job_unlink(j);
 
         sd_bus_track_unref(j->bus_track);
         strv_free(j->deserialized_clients);
@@ -241,6 +259,7 @@ int job_install_deserialized(Job *j) {
 
         *pj = j;
         j->installed = true;
+        j->reloaded = true;
 
         if (j->state == JOB_RUNNING)
                 j->unit->manager->n_running_jobs++;
@@ -844,6 +863,19 @@ static void job_fail_dependencies(Unit *u, UnitDependency d) {
         }
 }
 
+static int job_save_pending_finished_job(Job *j) {
+        int r;
+
+        assert(j);
+
+        r = set_ensure_allocated(&j->manager->pending_finished_jobs, NULL);
+        if (r < 0)
+                return r;
+
+        job_unlink(j);
+        return set_put(j->manager->pending_finished_jobs, j);
+}
+
 int job_finish_and_invalidate(Job *j, JobResult result, bool recursive, bool already) {
         Unit *u;
         Unit *other;
@@ -883,7 +915,11 @@ int job_finish_and_invalidate(Job *j, JobResult result, bool recursive, bool alr
                 j->manager->n_failed_jobs++;
 
         job_uninstall(j);
-        job_free(j);
+        /* Keep jobs started before the reload to send singal later, free all others */
+        if (!MANAGER_IS_RELOADING(j->manager) ||
+            !j->reloaded ||
+            job_save_pending_finished_job(j) < 0)
+                job_free(j);
 
         /* Fail depending jobs on failure */
         if (result != JOB_DONE && recursive) {
index ccb8e1b67415c7daeb944cd27c466a67f1f633a9..338670e39351f6a44690a6ca1d2ec56254f90680 100644 (file)
@@ -162,10 +162,12 @@ struct Job {
         bool irreversible:1;
         bool in_gc_queue:1;
         bool ref_by_private_bus:1;
+        bool reloaded:1;
 };
 
 Job* job_new(Unit *unit, JobType type);
 Job* job_new_raw(Unit *unit);
+void job_unlink(Job *job);
 void job_free(Job *job);
 Job* job_install(Job *j);
 int job_install_deserialized(Job *j);
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 dd8d1874fd22eeedf5e6ef56a16078f8f91c6e44..2a11e4bbd05cb891c503a9696dcb7e3ab7e08a31 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"
@@ -101,7 +100,7 @@ int config_parse_unit_deps(
 
                 r = unit_name_printf(u, word, &k);
                 if (r < 0) {
-                        log_syntax(unit, LOG_ERR, filename, line, r, "Failed to resolve specifiers, ignoring: %m");
+                        log_syntax(unit, LOG_ERR, filename, line, r, "Failed to resolve unit specifiers in '%s', ignoring: %m", word);
                         continue;
                 }
 
@@ -154,7 +153,7 @@ int config_parse_unit_string_printf(
 
         r = unit_full_printf(u, 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 in '%s', ignoring: %m", rvalue);
                 return 0;
         }
 
@@ -184,7 +183,7 @@ int config_parse_unit_strv_printf(
 
         r = unit_full_printf(u, 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 in '%s', ignoring: %m", rvalue);
                 return 0;
         }
 
@@ -224,7 +223,7 @@ int config_parse_unit_path_printf(
         r = unit_full_printf(u, rvalue, &k);
         if (r < 0) {
                 log_syntax(unit, LOG_ERR, filename, line, r,
-                           "Failed to resolve unit specifiers in \"%s\"%s: %m",
+                           "Failed to resolve unit specifiers in '%s'%s: %m",
                            rvalue, fatal ? "" : ", ignoring");
                 return fatal ? -ENOEXEC : 0;
         }
@@ -276,7 +275,7 @@ int config_parse_unit_path_strv_printf(
                 r = unit_full_printf(u, word, &k);
                 if (r < 0) {
                         log_syntax(unit, LOG_ERR, filename, line, r,
-                                   "Failed to resolve unit specifiers on \"%s\", ignoring: %m", word);
+                                   "Failed to resolve unit specifiers in '%s', ignoring: %m", word);
                         return 0;
                 }
 
@@ -338,7 +337,7 @@ int config_parse_socket_listen(const char *unit,
                 p->type = ltype;
                 r = unit_full_printf(UNIT(s), rvalue, &p->path);
                 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 in '%s', ignoring: %m", rvalue);
                         return 0;
                 }
 
@@ -350,13 +349,13 @@ 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 in '%s', ignoring: %m", rvalue);
                         return 0;
                 }
 
                 r = socket_address_parse_netlink(&p->address, k);
                 if (r < 0) {
-                        log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse address value, ignoring: %s", rvalue);
+                        log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse address value in '%s', ignoring: %m", k);
                         return 0;
                 }
 
@@ -366,14 +365,14 @@ 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 in '%s', ignoring: %m", rvalue);
                         return 0;
                 }
 
                 r = socket_address_parse_and_warn(&p->address, k);
                 if (r < 0) {
                         if (r != -EAFNOSUPPORT)
-                                log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse address value, ignoring: %s", rvalue);
+                                log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse address value in '%s', ignoring: %m", k);
                         return 0;
                 }
 
@@ -427,7 +426,7 @@ int config_parse_socket_protocol(const char *unit,
 
         r = socket_protocol_from_name(rvalue);
         if (r < 0) {
-                log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid socket protocol, ignoring: %s", rvalue);
+                log_syntax(unit, LOG_ERR, filename, line, r, "Invalid socket protocol '%s', ignoring: %m", rvalue);
                 return 0;
         } else if (!IN_SET(r, IPPROTO_UDPLITE, IPPROTO_SCTP)) {
                 log_syntax(unit, LOG_ERR, filename, line, 0, "Socket protocol not supported, ignoring: %s", rvalue);
@@ -496,8 +495,7 @@ int config_parse_exec_nice(
                 if (r == -ERANGE)
                         log_syntax(unit, LOG_ERR, filename, line, r, "Nice priority out of range, ignoring: %s", rvalue);
                 else
-                        log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse nice priority, ignoring: %s", rvalue);
-
+                        log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse nice priority '%s', ignoring: %m", rvalue);
                 return 0;
         }
 
@@ -507,16 +505,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 +525,17 @@ 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 < 0) {
+                if (r == -ERANGE)
+                        log_syntax(unit, LOG_ERR, filename, line, r, "OOM score adjust value out of range, ignoring: %s", rvalue);
+                else
+                        log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse the OOM score adjust value '%s', ignoring: %m", rvalue);
                 return 0;
         }
 
@@ -625,7 +627,7 @@ int config_parse_exec(
                 r = unit_full_printf(u, f, &path);
                 if (r < 0) {
                         log_syntax(unit, LOG_ERR, filename, line, r,
-                                   "Failed to resolve unit specifiers on %s%s: %m",
+                                   "Failed to resolve unit specifiers in '%s'%s: %m",
                                    f, ignore ? ", ignoring" : "");
                         return ignore ? 0 : -ENOEXEC;
                 }
@@ -633,7 +635,7 @@ int config_parse_exec(
                 if (isempty(path)) {
                         /* First word is either "-" or "@" with no command. */
                         log_syntax(unit, LOG_ERR, filename, line, 0,
-                                   "Empty path in command line%s: \"%s\"",
+                                   "Empty path in command line%s: '%s'",
                                    ignore ? ", ignoring" : "", rvalue);
                         return ignore ? 0 : -ENOEXEC;
                 }
@@ -739,7 +741,7 @@ int config_parse_exec(
                         r = unit_full_printf(u, word, &resolved);
                         if (r < 0) {
                                 log_syntax(unit, LOG_ERR, filename, line, r,
-                                           "Failed to resolve unit specifiers on %s%s: %m",
+                                           "Failed to resolve unit specifiers in %s%s: %m",
                                            word, ignore ? ", ignoring" : "");
                                 return ignore ? 0 : -ENOEXEC;
                         }
@@ -793,27 +795,23 @@ int config_parse_socket_bindtodevice(
                 void *userdata) {
 
         Socket *s = data;
-        char *n;
 
         assert(filename);
         assert(lvalue);
         assert(rvalue);
         assert(data);
 
-        if (rvalue[0] && !streq(rvalue, "*")) {
-                if (!ifname_valid(rvalue)) {
-                        log_syntax(unit, LOG_ERR, filename, line, 0, "Interface name is invalid, ignoring: %s", rvalue);
-                        return 0;
-                }
+        if (isempty(rvalue) || streq(rvalue, "*")) {
+                s->bind_to_device = mfree(s->bind_to_device);
+                return 0;
+        }
 
-                n = strdup(rvalue);
-                if (!n)
-                        return log_oom();
-        } else
-                n = NULL;
+        if (!ifname_valid(rvalue)) {
+                log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid interface name, ignoring: %s", rvalue);
+                return 0;
+        }
 
-        free(s->bind_to_device);
-        s->bind_to_device = n;
+        free_and_strdup(&s->bind_to_device, rvalue);
 
         return 0;
 }
@@ -847,7 +845,7 @@ int config_parse_exec_input(
 
                 r = unit_full_printf(u, n, &resolved);
                 if (r < 0)
-                        return log_syntax(unit, LOG_ERR, filename, line, r, "Failed to resolve unit specifiers on %s: %m", n);
+                        return log_syntax(unit, LOG_ERR, filename, line, r, "Failed to resolve unit specifiers in '%s': %m", n);
 
                 if (isempty(resolved))
                         resolved = mfree(resolved);
@@ -865,7 +863,7 @@ int config_parse_exec_input(
 
                 r = unit_full_printf(u, n, &resolved);
                 if (r < 0)
-                        return log_syntax(unit, LOG_ERR, filename, line, r, "Failed to resolve unit specifiers on %s: %m", n);
+                        return log_syntax(unit, LOG_ERR, filename, line, r, "Failed to resolve unit specifiers in '%s': %m", n);
 
                 if (!path_is_absolute(resolved)) {
                         log_syntax(unit, LOG_ERR, filename, line, 0, "file: requires an absolute path name: %s", resolved);
@@ -926,11 +924,11 @@ int config_parse_exec_input_text(
 
         r = cunescape(rvalue, 0, &unescaped);
         if (r < 0)
-                return log_syntax(unit, LOG_ERR, filename, line, r, "Failed to decode C escaped text: %s", rvalue);
+                return log_syntax(unit, LOG_ERR, filename, line, r, "Failed to decode C escaped text '%s': %m", rvalue);
 
         r = unit_full_printf(u, unescaped, &resolved);
         if (r < 0)
-                return log_syntax(unit, LOG_ERR, filename, line, r, "Failed to resolve specifiers: %s", unescaped);
+                return log_syntax(unit, LOG_ERR, filename, line, r, "Failed to resolve unit specifiers in '%s': %m", unescaped);
 
         sz = strlen(resolved);
         if (c->stdin_data_size + sz + 1 < c->stdin_data_size || /* check for overflow */
@@ -1034,7 +1032,7 @@ int config_parse_exec_output(
         if (n) {
                 r = unit_full_printf(u, n, &resolved);
                 if (r < 0)
-                        return log_syntax(unit, LOG_ERR, filename, line, r, "Failed to resolve unit specifiers on %s: %m", n);
+                        return log_syntax(unit, LOG_ERR, filename, line, r, "Failed to resolve unit specifiers in %s: %m", n);
 
                 if (isempty(resolved))
                         resolved = mfree(resolved);
@@ -1049,7 +1047,7 @@ int config_parse_exec_output(
 
                 r = unit_full_printf(u, n, &resolved);
                 if (r < 0)
-                        return log_syntax(unit, LOG_ERR, filename, line, r, "Failed to resolve unit specifiers on %s: %m", n);
+                        return log_syntax(unit, LOG_ERR, filename, line, r, "Failed to resolve unit specifiers in %s: %m", n);
 
                 if (!path_is_absolute(resolved)) {
                         log_syntax(unit, LOG_ERR, filename, line, 0, "file: requires an absolute path name: %s", resolved);
@@ -1209,7 +1207,7 @@ int config_parse_exec_cpu_sched_prio(const char *unit,
 
         r = safe_atoi(rvalue, &i);
         if (r < 0) {
-                log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse CPU scheduling policy, ignoring: %s", rvalue);
+                log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse CPU scheduling priority, ignoring: %s", rvalue);
                 return 0;
         }
 
@@ -1304,11 +1302,9 @@ int config_parse_exec_secure_bits(const char *unit,
         }
 
         r = secure_bits_from_string(rvalue);
-        if (r == -ENOMEM)
-                return log_oom();
         if (r < 0) {
                 log_syntax(unit, LOG_WARNING, filename, line, r,
-                           "Invalid syntax, ignoring: %s", rvalue);
+                           "Failed to parse secure bits, ignoring: %s", rvalue);
                 return 0;
         }
 
@@ -1349,10 +1345,8 @@ int config_parse_capability_set(
         /* else "AmbientCapabilities" initialized to all bits off */
 
         r = capability_set_from_string(rvalue, &sum);
-        if (r == -ENOMEM)
-                return log_oom();
         if (r < 0) {
-                log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse word: %s", rvalue);
+                log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse %s= specifier '%s', ignoring: %m", lvalue, rvalue);
                 return 0;
         }
 
@@ -1370,47 +1364,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,
@@ -1432,10 +1385,14 @@ int config_parse_sysv_priority(const char *unit,
         assert(data);
 
         r = safe_atoi(rvalue, &i);
-        if (r < 0 || i < 0) {
+        if (r < 0) {
                 log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse SysV start priority, ignoring: %s", rvalue);
                 return 0;
         }
+        if (i < 0) {
+                log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid SysV start priority, ignoring: %s", rvalue);
+                return 0;
+        }
 
         *priority = (int) i;
         return 0;
@@ -1467,7 +1424,7 @@ int config_parse_exec_mount_flags(
 
         r = mount_propagation_flags_from_string(rvalue, &c->mount_flags);
         if (r < 0)
-                log_syntax(unit, LOG_ERR, filename, line, 0, "Failed to parse mount flag %s, ignoring.", rvalue);
+                log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse mount flag %s, ignoring: %m", rvalue);
 
         return 0;
 }
@@ -1510,13 +1467,12 @@ int config_parse_exec_selinux_context(
         r = unit_full_printf(u, rvalue, &k);
         if (r < 0) {
                 log_syntax(unit, LOG_ERR, filename, line, r,
-                           "Failed to resolve specifiers%s: %m",
-                           ignore ? ", ignoring" : "");
+                           "Failed to resolve unit specifiers in '%s'%s: %m",
+                           rvalue, ignore ? ", ignoring" : "");
                 return ignore ? 0 : -ENOEXEC;
         }
 
-        free(c->selinux_context);
-        c->selinux_context = k;
+        free_and_replace(c->selinux_context, k);
         c->selinux_context_ignore = ignore;
 
         return 0;
@@ -1560,13 +1516,12 @@ int config_parse_exec_apparmor_profile(
         r = unit_full_printf(u, rvalue, &k);
         if (r < 0) {
                 log_syntax(unit, LOG_ERR, filename, line, r,
-                           "Failed to resolve specifiers%s: %m",
-                           ignore ? ", ignoring" : "");
+                           "Failed to resolve unit specifiers in '%s'%s: %m",
+                           rvalue, ignore ? ", ignoring" : "");
                 return ignore ? 0 : -ENOEXEC;
         }
 
-        free(c->apparmor_profile);
-        c->apparmor_profile = k;
+        free_and_replace(c->apparmor_profile, k);
         c->apparmor_profile_ignore = ignore;
 
         return 0;
@@ -1610,13 +1565,12 @@ int config_parse_exec_smack_process_label(
         r = unit_full_printf(u, rvalue, &k);
         if (r < 0) {
                 log_syntax(unit, LOG_ERR, filename, line, r,
-                           "Failed to resolve specifiers%s: %m",
-                           ignore ? ", ignoring" : "");
+                           "Failed to resolve unit specifiers in '%s'%s: %m",
+                           rvalue, ignore ? ", ignoring" : "");
                 return ignore ? 0 : -ENOEXEC;
         }
 
-        free(c->smack_process_label);
-        c->smack_process_label = k;
+        free_and_replace(c->smack_process_label, k);
         c->smack_process_label_ignore = ignore;
 
         return 0;
@@ -1637,7 +1591,7 @@ int config_parse_timer(const char *unit,
         usec_t usec = 0;
         TimerValue *v;
         TimerBase b;
-        CalendarSpec *c = NULL;
+        _cleanup_(calendar_spec_freep) CalendarSpec *c = NULL;
         Unit *u = userdata;
         _cleanup_free_ char *k = NULL;
         int r;
@@ -1661,7 +1615,7 @@ int config_parse_timer(const char *unit,
 
         r = unit_full_printf(u, rvalue, &k);
         if (r < 0) {
-                log_syntax(unit, LOG_ERR, filename, line, r, "Failed to resolve unit specifiers in %s, ignoring: %m", rvalue);
+                log_syntax(unit, LOG_ERR, filename, line, r, "Failed to resolve unit specifiers in '%s', ignoring: %m", rvalue);
                 return 0;
         }
 
@@ -1670,22 +1624,19 @@ int config_parse_timer(const char *unit,
                         log_syntax(unit, LOG_ERR, filename, line, 0, "Failed to parse calendar specification, ignoring: %s", k);
                         return 0;
                 }
-        } else {
+        } else
                 if (parse_sec(k, &usec) < 0) {
                         log_syntax(unit, LOG_ERR, filename, line, 0, "Failed to parse timer value, ignoring: %s", k);
                         return 0;
                 }
-        }
 
         v = new0(TimerValue, 1);
-        if (!v) {
-                calendar_spec_free(c);
+        if (!v)
                 return log_oom();
-        }
 
         v->base = b;
         v->value = usec;
-        v->calendar_spec = c;
+        v->calendar_spec = TAKE_PTR(c);
 
         LIST_PREPEND(value, t->values, v);
 
@@ -1721,7 +1672,7 @@ int config_parse_trigger_unit(
 
         r = unit_name_printf(u, rvalue, &p);
         if (r < 0) {
-                log_syntax(unit, LOG_ERR, filename, line, r, "Failed to resolve specifiers, ignoring: %m");
+                log_syntax(unit, LOG_ERR, filename, line, r, "Failed to resolve unit specifiers in %s, ignoring: %m", rvalue);
                 return 0;
         }
 
@@ -1780,10 +1731,12 @@ int config_parse_path_spec(const char *unit,
 
         r = unit_full_printf(UNIT(p), rvalue, &k);
         if (r < 0) {
-                log_syntax(unit, LOG_ERR, filename, line, r, "Failed to resolve unit specifiers on %s. Ignoring.", rvalue);
+                log_syntax(unit, LOG_ERR, filename, line, r, "Failed to resolve unit specifiers in %s, ignoring: %m", rvalue);
                 return 0;
         }
 
+        path_kill_slashes(k);
+
         if (!path_is_absolute(k)) {
                 log_syntax(unit, LOG_ERR, filename, line, 0, "Path is not absolute, ignoring: %s", k);
                 return 0;
@@ -1794,8 +1747,7 @@ int config_parse_path_spec(const char *unit,
                 return log_oom();
 
         s->unit = UNIT(p);
-        s->path = path_kill_slashes(k);
-        k = NULL;
+        s->path = TAKE_PTR(k);
         s->type = b;
         s->inotify_fd = -1;
 
@@ -1829,7 +1781,7 @@ int config_parse_socket_service(
 
         r = unit_name_printf(UNIT(s), rvalue, &p);
         if (r < 0) {
-                log_syntax(unit, LOG_ERR, filename, line, r, "Failed to resolve specifiers: %s", rvalue);
+                log_syntax(unit, LOG_ERR, filename, line, r, "Failed to resolve unit specifiers in %s: %m", rvalue);
                 return -ENOEXEC;
         }
 
@@ -1877,7 +1829,7 @@ int config_parse_fdname(
 
         r = unit_full_printf(UNIT(s), rvalue, &p);
         if (r < 0) {
-                log_syntax(unit, LOG_ERR, filename, line, r, "Failed to resolve specifiers, ignoring: %s", rvalue);
+                log_syntax(unit, LOG_ERR, filename, line, r, "Failed to resolve unit specifiers in '%s', ignoring: %m", rvalue);
                 return 0;
         }
 
@@ -1926,7 +1878,7 @@ int config_parse_service_sockets(
 
                 r = unit_name_printf(UNIT(s), word, &k);
                 if (r < 0) {
-                        log_syntax(unit, LOG_ERR, filename, line, r, "Failed to resolve specifiers, ignoring: %m");
+                        log_syntax(unit, LOG_ERR, filename, line, r, "Failed to resolve unit specifiers in '%s', ignoring: %m", word);
                         continue;
                 }
 
@@ -1970,12 +1922,12 @@ int config_parse_bus_name(
 
         r = unit_full_printf(u, 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 in %s, ignoring: %m", rvalue);
                 return 0;
         }
 
         if (!service_name_is_valid(k)) {
-                log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid bus name %s, ignoring.", k);
+                log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid bus name, ignoring: %s", k);
                 return 0;
         }
 
@@ -2073,7 +2025,8 @@ int config_parse_user_group(
                 void *data,
                 void *userdata) {
 
-        char **user = data, *n;
+        _cleanup_free_ char *k = NULL;
+        char **user = data;
         Unit *u = userdata;
         int r;
 
@@ -2082,29 +2035,23 @@ int config_parse_user_group(
         assert(rvalue);
         assert(u);
 
-        if (isempty(rvalue))
-                n = NULL;
-        else {
-                _cleanup_free_ char *k = NULL;
-
-                r = unit_full_printf(u, rvalue, &k);
-                if (r < 0) {
-                        log_syntax(unit, LOG_ERR, filename, line, r, "Failed to resolve unit specifiers in %s: %m", rvalue);
-                        return -ENOEXEC;
-                }
-
-                if (!valid_user_group_name_or_id(k)) {
-                        log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid user/group name or numeric ID: %s", k);
-                        return -ENOEXEC;
-                }
+        if (isempty(rvalue)) {
+                *user = mfree(*user);
+                return 0;
+        }
 
-                n = TAKE_PTR(k);
+        r = unit_full_printf(u, rvalue, &k);
+        if (r < 0) {
+                log_syntax(unit, LOG_ERR, filename, line, r, "Failed to resolve unit specifiers in %s: %m", rvalue);
+                return -ENOEXEC;
         }
 
-        free(*user);
-        *user = n;
+        if (!valid_user_group_name_or_id(k)) {
+                log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid user/group name or numeric ID: %s", k);
+                return -ENOEXEC;
+        }
 
-        return 0;
+        return free_and_replace(*user, k);
 }
 
 int config_parse_user_group_strv(
@@ -2121,7 +2068,7 @@ int config_parse_user_group_strv(
 
         char ***users = data;
         Unit *u = userdata;
-        const char *p;
+        const char *p = rvalue;
         int r;
 
         assert(filename);
@@ -2134,7 +2081,6 @@ int config_parse_user_group_strv(
                 return 0;
         }
 
-        p = rvalue;
         for (;;) {
                 _cleanup_free_ char *word = NULL, *k = NULL;
 
@@ -2263,7 +2209,7 @@ int config_parse_unit_env_file(const char *unit,
 
         r = unit_full_printf(u, rvalue, &n);
         if (r < 0) {
-                log_syntax(unit, LOG_ERR, filename, line, r, "Failed to resolve specifiers, ignoring: %s", rvalue);
+                log_syntax(unit, LOG_ERR, filename, line, r, "Failed to resolve unit specifiers in '%s', ignoring: %m", rvalue);
                 return 0;
         }
 
@@ -2325,7 +2271,7 @@ int config_parse_environ(
                         r = unit_full_printf(u, word, &k);
                         if (r < 0) {
                                 log_syntax(unit, LOG_ERR, filename, line, r,
-                                           "Failed to resolve specifiers, ignoring: %s", word);
+                                           "Failed to resolve unit specifiers in %s, ignoring: %m", word);
                                 continue;
                         }
                 } else
@@ -2357,10 +2303,10 @@ int config_parse_pass_environ(
                 void *data,
                 void *userdata) {
 
-        const char *whole_rvalue = rvalue;
         _cleanup_strv_free_ char **n = NULL;
         size_t nlen = 0, nbufsize = 0;
         char*** passenv = data;
+        const char *p = rvalue;
         Unit *u = userdata;
         int r;
 
@@ -2378,14 +2324,14 @@ int config_parse_pass_environ(
         for (;;) {
                 _cleanup_free_ char *word = NULL, *k = NULL;
 
-                r = extract_first_word(&rvalue, &word, NULL, EXTRACT_QUOTES);
+                r = extract_first_word(&p, &word, NULL, EXTRACT_QUOTES);
                 if (r == 0)
                         break;
                 if (r == -ENOMEM)
                         return log_oom();
                 if (r < 0) {
                         log_syntax(unit, LOG_ERR, filename, line, r,
-                                   "Trailing garbage in %s, ignoring: %s", lvalue, whole_rvalue);
+                                   "Trailing garbage in %s, ignoring: %s", lvalue, rvalue);
                         break;
                 }
 
@@ -2393,7 +2339,7 @@ int config_parse_pass_environ(
                         r = unit_full_printf(u, word, &k);
                         if (r < 0) {
                                 log_syntax(unit, LOG_ERR, filename, line, r,
-                                           "Failed to resolve specifiers, ignoring: %s", word);
+                                           "Failed to resolve specifiers in %s, ignoring: %m", word);
                                 continue;
                         }
                 } else
@@ -2434,9 +2380,9 @@ int config_parse_unset_environ(
                 void *userdata) {
 
         _cleanup_strv_free_ char **n = NULL;
-        const char *whole_rvalue = rvalue;
         size_t nlen = 0, nbufsize = 0;
         char*** unsetenv = data;
+        const char *p = rvalue;
         Unit *u = userdata;
         int r;
 
@@ -2454,14 +2400,14 @@ int config_parse_unset_environ(
         for (;;) {
                 _cleanup_free_ char *word = NULL, *k = NULL;
 
-                r = extract_first_word(&rvalue, &word, NULL, EXTRACT_CUNESCAPE|EXTRACT_QUOTES);
+                r = extract_first_word(&p, &word, NULL, EXTRACT_CUNESCAPE|EXTRACT_QUOTES);
                 if (r == 0)
                         break;
                 if (r == -ENOMEM)
                         return log_oom();
                 if (r < 0) {
                         log_syntax(unit, LOG_ERR, filename, line, r,
-                                   "Trailing garbage in %s, ignoring: %s", lvalue, whole_rvalue);
+                                   "Trailing garbage in %s, ignoring: %s", lvalue, rvalue);
                         break;
                 }
 
@@ -2469,7 +2415,7 @@ int config_parse_unset_environ(
                         r = unit_full_printf(u, word, &k);
                         if (r < 0) {
                                 log_syntax(unit, LOG_ERR, filename, line, r,
-                                           "Failed to resolve specifiers, ignoring: %s", word);
+                                           "Failed to resolve unit specifiers in %s, ignoring: %m", word);
                                 continue;
                         }
                 } else
@@ -2511,7 +2457,7 @@ int config_parse_log_extra_fields(
 
         ExecContext *c = data;
         Unit *u = userdata;
-        const char *p;
+        const char *p = rvalue;
         int r;
 
         assert(filename);
@@ -2524,14 +2470,14 @@ int config_parse_log_extra_fields(
                 return 0;
         }
 
-        for (p = rvalue;; ) {
+        for (;;) {
                 _cleanup_free_ char *word = NULL, *k = NULL;
                 struct iovec *t;
                 const char *eq;
 
                 r = extract_first_word(&p, &word, NULL, EXTRACT_CUNESCAPE|EXTRACT_QUOTES);
                 if (r == 0)
-                        break;
+                        return 0;
                 if (r == -ENOMEM)
                         return log_oom();
                 if (r < 0) {
@@ -2541,18 +2487,18 @@ int config_parse_log_extra_fields(
 
                 r = unit_full_printf(u, word, &k);
                 if (r < 0) {
-                        log_syntax(unit, LOG_ERR, filename, line, r, "Failed to resolve unit specifiers on %s, ignoring field: %m", word);
+                        log_syntax(unit, LOG_ERR, filename, line, r, "Failed to resolve unit specifiers in %s, ignoring: %m", word);
                         continue;
                 }
 
                 eq = strchr(k, '=');
                 if (!eq) {
-                        log_syntax(unit, LOG_ERR, filename, line, 0, "Log field lacks '=' character, ignoring field: %s", k);
+                        log_syntax(unit, LOG_ERR, filename, line, 0, "Log field lacks '=' character, ignoring: %s", k);
                         continue;
                 }
 
                 if (!journal_field_valid(k, eq-k, false)) {
-                        log_syntax(unit, LOG_ERR, filename, line, 0, "Log field name is invalid, ignoring field: %s", k);
+                        log_syntax(unit, LOG_ERR, filename, line, 0, "Log field name is invalid, ignoring: %s", k);
                         continue;
                 }
 
@@ -2565,8 +2511,6 @@ int config_parse_log_extra_fields(
 
                 k = NULL;
         }
-
-        return 0;
 }
 
 int config_parse_ip_tos(const char *unit,
@@ -2637,7 +2581,7 @@ int config_parse_unit_condition_path(
 
         r = unit_full_printf(u, rvalue, &p);
         if (r < 0) {
-                log_syntax(unit, LOG_ERR, filename, line, r, "Failed to resolve specifiers, ignoring: %s", rvalue);
+                log_syntax(unit, LOG_ERR, filename, line, r, "Failed to resolve unit specifiers in %s, ignoring: %m", rvalue);
                 return 0;
         }
 
@@ -2694,7 +2638,7 @@ int config_parse_unit_condition_string(
 
         r = unit_full_printf(u, rvalue, &s);
         if (r < 0) {
-                log_syntax(unit, LOG_ERR, filename, line, r, "Failed to resolve specifiers, ignoring: %s", rvalue);
+                log_syntax(unit, LOG_ERR, filename, line, r, "Failed to resolve unit specifiers in '%s', ignoring: %m", rvalue);
                 return 0;
         }
 
@@ -2773,8 +2717,8 @@ int config_parse_unit_requires_mounts_for(
                 void *data,
                 void *userdata) {
 
+        const char *p = rvalue;
         Unit *u = userdata;
-        const char *p;
         int r;
 
         assert(filename);
@@ -2782,7 +2726,7 @@ int config_parse_unit_requires_mounts_for(
         assert(rvalue);
         assert(data);
 
-        for (p = rvalue;; ) {
+        for (;;) {
                 _cleanup_free_ char *word = NULL, *resolved = NULL;
 
                 r = extract_first_word(&p, &word, NULL, EXTRACT_QUOTES);
@@ -2803,13 +2747,13 @@ int config_parse_unit_requires_mounts_for(
 
                 r = unit_full_printf(u, word, &resolved);
                 if (r < 0) {
-                        log_syntax(unit, LOG_ERR, filename, line, r, "Failed to resolve unit name \"%s\", ignoring: %m", word);
+                        log_syntax(unit, LOG_ERR, filename, line, r, "Failed to resolve unit specifiers in '%s', ignoring: %m", word);
                         continue;
                 }
 
                 r = unit_require_mounts_for(u, resolved, UNIT_DEPENDENCY_FILE);
                 if (r < 0) {
-                        log_syntax(unit, LOG_ERR, filename, line, r, "Failed to add required mount \"%s\", ignoring: %m", resolved);
+                        log_syntax(unit, LOG_ERR, filename, line, r, "Failed to add required mount '%s', ignoring: %m", resolved);
                         continue;
                 }
         }
@@ -2923,12 +2867,12 @@ int config_parse_syscall_filter(
 
                 r = extract_first_word(&p, &word, NULL, 0);
                 if (r == 0)
-                        break;
+                        return 0;
                 if (r == -ENOMEM)
                         return log_oom();
                 if (r < 0) {
                         log_syntax(unit, LOG_WARNING, filename, line, r, "Invalid syntax, ignoring: %s", rvalue);
-                        break;
+                        return 0;
                 }
 
                 r = parse_syscall_and_errno(word, &name, &num);
@@ -2943,8 +2887,6 @@ int config_parse_syscall_filter(
                 if (r < 0)
                         return r;
         }
-
-        return 0;
 }
 
 int config_parse_syscall_archs(
@@ -2959,8 +2901,8 @@ int config_parse_syscall_archs(
                 void *data,
                 void *userdata) {
 
+        const char *p = rvalue;
         Set **archs = data;
-        const char *p;
         int r;
 
         if (isempty(rvalue)) {
@@ -2972,7 +2914,7 @@ int config_parse_syscall_archs(
         if (r < 0)
                 return log_oom();
 
-        for (p = rvalue;;) {
+        for (;;) {
                 _cleanup_free_ char *word = NULL;
                 uint32_t a;
 
@@ -3092,9 +3034,9 @@ int config_parse_address_families(
                 }
 
                 af = af_from_name(word);
-                if (af <= 0)  {
+                if (af <= 0) {
                         log_syntax(unit, LOG_ERR, filename, line, 0,
-                                   "Failed to parse address family \"%s\", ignoring: %m", word);
+                                   "Failed to parse address family, ignoring: %s", word);
                         continue;
                 }
 
@@ -3178,6 +3120,7 @@ int config_parse_unit_slice(
                 void *data,
                 void *userdata) {
 
+        _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
         _cleanup_free_ char *k = NULL;
         Unit *u = userdata, *slice = NULL;
         int r;
@@ -3189,19 +3132,19 @@ int config_parse_unit_slice(
 
         r = unit_name_printf(u, rvalue, &k);
         if (r < 0) {
-                log_syntax(unit, LOG_ERR, filename, line, r, "Failed to resolve unit specifiers on %s. Ignoring.", rvalue);
+                log_syntax(unit, LOG_ERR, filename, line, r, "Failed to resolve unit specifiers in %s, ignoring: %m", rvalue);
                 return 0;
         }
 
-        r = manager_load_unit(u->manager, k, NULL, NULL, &slice);
+        r = manager_load_unit(u->manager, k, NULL, &error, &slice);
         if (r < 0) {
-                log_syntax(unit, LOG_ERR, filename, line, r, "Failed to load slice unit %s. Ignoring.", k);
+                log_syntax(unit, LOG_ERR, filename, line, r, "Failed to load slice unit %s, ignoring: %s", k, bus_error_message(&error, r));
                 return 0;
         }
 
         r = unit_set_slice(u, slice);
         if (r < 0) {
-                log_syntax(unit, LOG_ERR, filename, line, r, "Failed to assign slice %s to unit %s. Ignoring.", slice->id, u->id);
+                log_syntax(unit, LOG_ERR, filename, line, r, "Failed to assign slice %s to unit %s, ignoring: %m", slice->id, u->id);
                 return 0;
         }
 
@@ -3231,7 +3174,7 @@ int config_parse_cpu_weight(
 
         r = cg_weight_parse(rvalue, weight);
         if (r < 0) {
-                log_syntax(unit, LOG_ERR, filename, line, r, "CPU weight '%s' invalid. Ignoring.", rvalue);
+                log_syntax(unit, LOG_ERR, filename, line, r, "Invalid CPU weight '%s', ignoring: %m", rvalue);
                 return 0;
         }
 
@@ -3259,7 +3202,7 @@ int config_parse_cpu_shares(
 
         r = cg_cpu_shares_parse(rvalue, shares);
         if (r < 0) {
-                log_syntax(unit, LOG_ERR, filename, line, r, "CPU shares '%s' invalid. Ignoring.", rvalue);
+                log_syntax(unit, LOG_ERR, filename, line, r, "Invalid CPU shares '%s', ignoring: %m", rvalue);
                 return 0;
         }
 
@@ -3292,7 +3235,7 @@ int config_parse_cpu_quota(
 
         r = parse_percent_unbounded(rvalue);
         if (r <= 0) {
-                log_syntax(unit, LOG_ERR, filename, line, r, "CPU quota '%s' invalid. Ignoring.", rvalue);
+                log_syntax(unit, LOG_ERR, filename, line, r, "Invalid CPU quota '%s', ignoring.", rvalue);
                 return 0;
         }
 
@@ -3322,7 +3265,7 @@ int config_parse_memory_limit(
                 if (r < 0) {
                         r = parse_size(rvalue, 1024, &bytes);
                         if (r < 0) {
-                                log_syntax(unit, LOG_ERR, filename, line, r, "Memory limit '%s' invalid. Ignoring.", rvalue);
+                                log_syntax(unit, LOG_ERR, filename, line, r, "Invalid memory limit '%s', ignoring: %m", rvalue);
                                 return 0;
                         }
                 } else
@@ -3330,7 +3273,7 @@ int config_parse_memory_limit(
 
                 if (bytes >= UINT64_MAX ||
                     (bytes <= 0 && !streq(lvalue, "MemorySwapMax"))) {
-                        log_syntax(unit, LOG_ERR, filename, line, 0, "Memory limit '%s' out of range. Ignoring.", rvalue);
+                        log_syntax(unit, LOG_ERR, filename, line, 0, "Memory limit '%s' out of range, ignoring.", rvalue);
                         return 0;
                 }
         }
@@ -3381,14 +3324,14 @@ int config_parse_tasks_max(
         if (r < 0) {
                 r = safe_atou64(rvalue, &v);
                 if (r < 0) {
-                        log_syntax(unit, LOG_ERR, filename, line, r, "Maximum tasks value '%s' invalid. Ignoring.", rvalue);
+                        log_syntax(unit, LOG_ERR, filename, line, r, "Invalid maximum tasks value '%s', ignoring: %m", rvalue);
                         return 0;
                 }
         } else
                 v = system_tasks_max_scale(r, 100U);
 
         if (v <= 0 || v >= UINT64_MAX) {
-                log_syntax(unit, LOG_ERR, filename, line, 0, "Maximum tasks value '%s' out of range. Ignoring.", rvalue);
+                log_syntax(unit, LOG_ERR, filename, line, 0, "Maximum tasks value '%s' out of range, ignoring.", rvalue);
                 return 0;
         }
 
@@ -3452,7 +3395,7 @@ int config_parse_delegate(
 
                         cc = cgroup_controller_from_string(word);
                         if (cc < 0) {
-                                log_syntax(unit, LOG_ERR, filename, line, r, "Invalid controller name '%s', ignoring", rvalue);
+                                log_syntax(unit, LOG_ERR, filename, line, r, "Invalid controller name '%s', ignoring", word);
                                 continue;
                         }
 
@@ -3485,11 +3428,10 @@ int config_parse_device_allow(
                 void *data,
                 void *userdata) {
 
-        _cleanup_free_ char *path = NULL, *t = NULL;
+        _cleanup_free_ char *path = NULL, *resolved = NULL;
         CGroupContext *c = data;
         CGroupDeviceAllow *a;
-        const char *m = NULL;
-        size_t n;
+        const char *p = rvalue;
         int r;
 
         if (isempty(rvalue)) {
@@ -3499,32 +3441,35 @@ int config_parse_device_allow(
                 return 0;
         }
 
-        r = unit_full_printf(userdata, rvalue, &t);
+        r = extract_first_word(&p, &path, NULL, EXTRACT_QUOTES);
+        if (r == -ENOMEM)
+                return log_oom();
         if (r < 0) {
                 log_syntax(unit, LOG_WARNING, filename, line, r,
-                           "Failed to resolve specifiers in %s, ignoring: %m",
-                           rvalue);
+                           "Invalid syntax, ignoring: %s", rvalue);
+                return 0;
+        }
+        if (r == 0) {
+                log_syntax(unit, LOG_WARNING, filename, line, 0,
+                           "Failed to extract device path and rights from '%s', ignoring.", rvalue);
                 return 0;
         }
 
-        n = strcspn(t, WHITESPACE);
-
-        path = strndup(t, n);
-        if (!path)
-                return log_oom();
-
-        if (!is_deviceallow_pattern(path) &&
-            !path_startswith(path, "/run/systemd/inaccessible/")) {
-                log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid device node path '%s'. Ignoring.", path);
+        r = unit_full_printf(userdata, path, &resolved);
+        if (r < 0) {
+                log_syntax(unit, LOG_WARNING, filename, line, r,
+                           "Failed to resolve unit specifiers in '%s', ignoring: %m", path);
                 return 0;
         }
 
-        m = t + n + strspn(t + n, WHITESPACE);
-        if (isempty(m))
-                m = "rwm";
+        if (!is_deviceallow_pattern(resolved) &&
+            !path_startswith(resolved, "/run/systemd/inaccessible/")) {
+                log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid device node path '%s', ignoring.", resolved);
+                return 0;
+        }
 
-        if (!in_charset(m, "rwm")) {
-                log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid device rights '%s'. Ignoring.", m);
+        if (!isempty(p) && !in_charset(p, "rwm")) {
+                log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid device rights '%s', ignoring.", p);
                 return 0;
         }
 
@@ -3532,10 +3477,10 @@ int config_parse_device_allow(
         if (!a)
                 return log_oom();
 
-        a->path = TAKE_PTR(path);
-        a->r = !!strchr(m, 'r');
-        a->w = !!strchr(m, 'w');
-        a->m = !!strchr(m, 'm');
+        a->path = TAKE_PTR(resolved);
+        a->r = isempty(p) || !!strchr(p, 'r');
+        a->w = isempty(p) || !!strchr(p, 'w');
+        a->m = isempty(p) || !!strchr(p, 'm');
 
         LIST_PREPEND(device_allow, c->device_allow, a);
         return 0;
@@ -3562,7 +3507,7 @@ int config_parse_io_weight(
 
         r = cg_weight_parse(rvalue, weight);
         if (r < 0) {
-                log_syntax(unit, LOG_ERR, filename, line, r, "IO weight '%s' invalid. Ignoring.", rvalue);
+                log_syntax(unit, LOG_ERR, filename, line, r, "Invalid IO weight '%s', ignoring.", rvalue);
                 return 0;
         }
 
@@ -3581,12 +3526,11 @@ int config_parse_io_device_weight(
                 void *data,
                 void *userdata) {
 
-        _cleanup_free_ char *path = NULL;
+        _cleanup_free_ char *path = NULL, *resolved = NULL;
         CGroupIODeviceWeight *w;
         CGroupContext *c = data;
-        const char *weight;
+        const char *p = rvalue;
         uint64_t u;
-        size_t n;
         int r;
 
         assert(filename);
@@ -3600,28 +3544,36 @@ int config_parse_io_device_weight(
                 return 0;
         }
 
-        n = strcspn(rvalue, WHITESPACE);
-        weight = rvalue + n;
-        weight += strspn(weight, WHITESPACE);
-
-        if (isempty(weight)) {
-                log_syntax(unit, LOG_ERR, filename, line, 0, "Expected block device and device weight. Ignoring.");
+        r = extract_first_word(&p, &path, NULL, EXTRACT_QUOTES);
+        if (r == -ENOMEM)
+                return log_oom();
+        if (r < 0) {
+                log_syntax(unit, LOG_WARNING, filename, line, r,
+                           "Invalid syntax, ignoring: %s", rvalue);
+                return 0;
+        }
+        if (r == 0 || isempty(p)) {
+                log_syntax(unit, LOG_WARNING, filename, line, 0,
+                           "Failed to extract device path and weight from '%s', ignoring.", rvalue);
                 return 0;
         }
 
-        path = strndup(rvalue, n);
-        if (!path)
-                return log_oom();
+        r = unit_full_printf(userdata, path, &resolved);
+        if (r < 0) {
+                log_syntax(unit, LOG_WARNING, filename, line, r,
+                           "Failed to resolve unit specifiers in '%s', ignoring: %m", path);
+                return 0;
+        }
 
-        if (!path_startswith(path, "/dev") &&
-            !path_startswith(path, "/run/systemd/inaccessible/")) {
-                log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid device node path '%s'. Ignoring.", path);
+        if (!path_startswith(resolved, "/dev") &&
+            !path_startswith(resolved, "/run/systemd/inaccessible/")) {
+                log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid device node path '%s', ignoring.", resolved);
                 return 0;
         }
 
-        r = cg_weight_parse(weight, &u);
+        r = cg_weight_parse(p, &u);
         if (r < 0) {
-                log_syntax(unit, LOG_ERR, filename, line, r, "IO weight '%s' invalid. Ignoring.", weight);
+                log_syntax(unit, LOG_ERR, filename, line, r, "IO weight '%s' invalid, ignoring: %m", p);
                 return 0;
         }
 
@@ -3631,8 +3583,7 @@ int config_parse_io_device_weight(
         if (!w)
                 return log_oom();
 
-        w->path = TAKE_PTR(path);
-
+        w->path = TAKE_PTR(resolved);
         w->weight = u;
 
         LIST_PREPEND(device_weights, c->io_device_weights, w);
@@ -3651,13 +3602,12 @@ int config_parse_io_limit(
                 void *data,
                 void *userdata) {
 
-        _cleanup_free_ char *path = NULL;
+        _cleanup_free_ char *path = NULL, *resolved = NULL;
         CGroupIODeviceLimit *l = NULL, *t;
         CGroupContext *c = data;
         CGroupIOLimitType type;
-        const char *limit;
+        const char *p = rvalue;
         uint64_t num;
-        size_t n;
         int r;
 
         assert(filename);
@@ -3673,37 +3623,45 @@ int config_parse_io_limit(
                 return 0;
         }
 
-        n = strcspn(rvalue, WHITESPACE);
-        limit = rvalue + n;
-        limit += strspn(limit, WHITESPACE);
-
-        if (!*limit) {
-                log_syntax(unit, LOG_ERR, filename, line, 0, "Expected space separated pair of device node and bandwidth. Ignoring.");
+        r = extract_first_word(&p, &path, NULL, EXTRACT_QUOTES);
+        if (r == -ENOMEM)
+                return log_oom();
+        if (r < 0) {
+                log_syntax(unit, LOG_WARNING, filename, line, r,
+                           "Invalid syntax, ignoring: %s", rvalue);
+                return 0;
+        }
+        if (r == 0 || isempty(p)) {
+                log_syntax(unit, LOG_WARNING, filename, line, 0,
+                           "Failed to extract device node and bandwidth from '%s', ignoring.", rvalue);
                 return 0;
         }
 
-        path = strndup(rvalue, n);
-        if (!path)
-                return log_oom();
+        r = unit_full_printf(userdata, path, &resolved);
+        if (r < 0) {
+                log_syntax(unit, LOG_WARNING, filename, line, r,
+                           "Failed to resolve unit specifiers in '%s', ignoring: %m", path);
+                return 0;
+        }
 
-        if (!path_startswith(path, "/dev") &&
-            !path_startswith(path, "/run/systemd/inaccessible/")) {
-                log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid device node path '%s'. Ignoring.", path);
+        if (!path_startswith(resolved, "/dev") &&
+            !path_startswith(resolved, "/run/systemd/inaccessible/")) {
+                log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid device node path '%s', ignoring.", resolved);
                 return 0;
         }
 
-        if (streq("infinity", limit)) {
+        if (streq("infinity", p)) {
                 num = CGROUP_LIMIT_MAX;
         } else {
-                r = parse_size(limit, 1000, &num);
+                r = parse_size(p, 1000, &num);
                 if (r < 0 || num <= 0) {
-                        log_syntax(unit, LOG_ERR, filename, line, r, "IO Limit '%s' invalid. Ignoring.", rvalue);
+                        log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid IO limit '%s', ignoring.", p);
                         return 0;
                 }
         }
 
         LIST_FOREACH(device_limits, t, c->io_device_limits) {
-                if (path_equal(path, t->path)) {
+                if (path_equal(resolved, t->path)) {
                         l = t;
                         break;
                 }
@@ -3716,7 +3674,7 @@ int config_parse_io_limit(
                 if (!l)
                         return log_oom();
 
-                l->path = TAKE_PTR(path);
+                l->path = TAKE_PTR(resolved);
                 for (ttype = 0; ttype < _CGROUP_IO_LIMIT_TYPE_MAX; ttype++)
                         l->limits[ttype] = cgroup_io_limit_defaults[ttype];
 
@@ -3749,7 +3707,7 @@ int config_parse_blockio_weight(
 
         r = cg_blkio_weight_parse(rvalue, weight);
         if (r < 0) {
-                log_syntax(unit, LOG_ERR, filename, line, r, "Block IO weight '%s' invalid. Ignoring.", rvalue);
+                log_syntax(unit, LOG_ERR, filename, line, r, "Invalid block IO weight '%s', ignoring: %m", rvalue);
                 return 0;
         }
 
@@ -3768,12 +3726,11 @@ int config_parse_blockio_device_weight(
                 void *data,
                 void *userdata) {
 
-        _cleanup_free_ char *path = NULL;
+        _cleanup_free_ char *path = NULL, *resolved = NULL;
         CGroupBlockIODeviceWeight *w;
         CGroupContext *c = data;
-        const char *weight;
+        const char *p = rvalue;
         uint64_t u;
-        size_t n;
         int r;
 
         assert(filename);
@@ -3787,28 +3744,36 @@ int config_parse_blockio_device_weight(
                 return 0;
         }
 
-        n = strcspn(rvalue, WHITESPACE);
-        weight = rvalue + n;
-        weight += strspn(weight, WHITESPACE);
-
-        if (isempty(weight)) {
-                log_syntax(unit, LOG_ERR, filename, line, 0, "Expected block device and device weight. Ignoring.");
+        r = extract_first_word(&p, &path, NULL, EXTRACT_QUOTES);
+        if (r == -ENOMEM)
+                return log_oom();
+        if (r < 0) {
+                log_syntax(unit, LOG_WARNING, filename, line, r,
+                           "Invalid syntax, ignoring: %s", rvalue);
+                return 0;
+        }
+        if (r == 0 || isempty(p)) {
+                log_syntax(unit, LOG_WARNING, filename, line, 0,
+                           "Failed to extract device node and weight from '%s', ignoring.", rvalue);
                 return 0;
         }
 
-        path = strndup(rvalue, n);
-        if (!path)
-                return log_oom();
+        r = unit_full_printf(userdata, path, &resolved);
+        if (r < 0) {
+                log_syntax(unit, LOG_WARNING, filename, line, r,
+                           "Failed to resolve unit specifiers in '%s', ignoring: %m", path);
+                return 0;
+        }
 
-        if (!path_startswith(path, "/dev") &&
-            !path_startswith(path, "/run/systemd/inaccessible/")) {
-                log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid device node path '%s'. Ignoring.", path);
+        if (!path_startswith(resolved, "/dev") &&
+            !path_startswith(resolved, "/run/systemd/inaccessible/")) {
+                log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid device node path '%s'. Ignoring.", resolved);
                 return 0;
         }
 
-        r = cg_blkio_weight_parse(weight, &u);
+        r = cg_blkio_weight_parse(p, &u);
         if (r < 0) {
-                log_syntax(unit, LOG_ERR, filename, line, r, "Block IO weight '%s' invalid. Ignoring.", weight);
+                log_syntax(unit, LOG_ERR, filename, line, r, "Invalid block IO weight '%s', ignoring: %m", p);
                 return 0;
         }
 
@@ -3818,8 +3783,7 @@ int config_parse_blockio_device_weight(
         if (!w)
                 return log_oom();
 
-        w->path = TAKE_PTR(path);
-
+        w->path = TAKE_PTR(resolved);
         w->weight = u;
 
         LIST_PREPEND(device_weights, c->blockio_device_weights, w);
@@ -3838,13 +3802,12 @@ int config_parse_blockio_bandwidth(
                 void *data,
                 void *userdata) {
 
-        _cleanup_free_ char *path = NULL;
+        _cleanup_free_ char *path = NULL, *resolved = NULL;
         CGroupBlockIODeviceBandwidth *b = NULL, *t;
         CGroupContext *c = data;
-        const char *bandwidth;
+        const char *p = rvalue;
         uint64_t bytes;
         bool read;
-        size_t n;
         int r;
 
         assert(filename);
@@ -3861,33 +3824,41 @@ int config_parse_blockio_bandwidth(
                 return 0;
         }
 
-        n = strcspn(rvalue, WHITESPACE);
-        bandwidth = rvalue + n;
-        bandwidth += strspn(bandwidth, WHITESPACE);
-
-        if (!*bandwidth) {
-                log_syntax(unit, LOG_ERR, filename, line, 0, "Expected space separated pair of device node and bandwidth. Ignoring.");
+        r = extract_first_word(&p, &path, NULL, EXTRACT_QUOTES);
+        if (r == -ENOMEM)
+                return log_oom();
+        if (r < 0) {
+                log_syntax(unit, LOG_WARNING, filename, line, r,
+                           "Invalid syntax, ignoring: %s", rvalue);
+                return 0;
+        }
+        if (r == 0 || isempty(p)) {
+                log_syntax(unit, LOG_WARNING, filename, line, 0,
+                           "Failed to extract device node and bandwidth from '%s', ignoring.", rvalue);
                 return 0;
         }
 
-        path = strndup(rvalue, n);
-        if (!path)
-                return log_oom();
+        r = unit_full_printf(userdata, path, &resolved);
+        if (r < 0) {
+                log_syntax(unit, LOG_WARNING, filename, line, r,
+                           "Failed to resolve unit specifiers in '%s', ignoring: %m", path);
+                return 0;
+        }
 
-        if (!path_startswith(path, "/dev") &&
-            !path_startswith(path, "/run/systemd/inaccessible/")) {
-                log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid device node path '%s'. Ignoring.", path);
+        if (!path_startswith(resolved, "/dev") &&
+            !path_startswith(resolved, "/run/systemd/inaccessible/")) {
+                log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid device node path '%s', ignoring.", resolved);
                 return 0;
         }
 
-        r = parse_size(bandwidth, 1000, &bytes);
+        r = parse_size(p, 1000, &bytes);
         if (r < 0 || bytes <= 0) {
-                log_syntax(unit, LOG_ERR, filename, line, r, "Block IO Bandwidth '%s' invalid. Ignoring.", rvalue);
+                log_syntax(unit, LOG_ERR, filename, line, r, "Invalid Block IO Bandwidth '%s', ignoring.", p);
                 return 0;
         }
 
         LIST_FOREACH(device_bandwidths, t, c->blockio_device_bandwidths) {
-                if (path_equal(path, t->path)) {
+                if (path_equal(resolved, t->path)) {
                         b = t;
                         break;
                 }
@@ -3898,7 +3869,7 @@ int config_parse_blockio_bandwidth(
                 if (!b)
                         return log_oom();
 
-                b->path = TAKE_PTR(path);
+                b->path = TAKE_PTR(resolved);
                 b->rbps = CGROUP_LIMIT_MAX;
                 b->wbps = CGROUP_LIMIT_MAX;
 
@@ -3993,13 +3964,25 @@ int config_parse_exec_directories(
                 r = unit_full_printf(u, word, &k);
                 if (r < 0) {
                         log_syntax(unit, LOG_ERR, filename, line, r,
-                                   "Failed to resolve specifiers in \"%s\", ignoring: %m", word);
+                                   "Failed to resolve unit specifiers in \"%s\", ignoring: %m", word);
+                        continue;
+                }
+
+                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_is_normalized(k) || path_is_absolute(k)) {
+                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;
                 }
 
@@ -4069,10 +4052,8 @@ int config_parse_set_status(
                         return log_oom();
 
                 r = set_put(*set, INT_TO_PTR(val));
-                if (r < 0) {
-                        log_syntax(unit, LOG_ERR, filename, line, r, "Unable to store: %s", word);
-                        return r;
-                }
+                if (r < 0)
+                        return log_oom();
         }
         if (!isempty(state))
                 log_syntax(unit, LOG_ERR, filename, line, 0, "Trailing garbage, ignoring.");
@@ -4094,7 +4075,7 @@ int config_parse_namespace_path_strv(
 
         Unit *u = userdata;
         char*** sv = data;
-        const char *cur;
+        const char *p = rvalue;
         int r;
 
         assert(filename);
@@ -4108,13 +4089,12 @@ int config_parse_namespace_path_strv(
                 return 0;
         }
 
-        cur = rvalue;
         for (;;) {
                 _cleanup_free_ char *word = NULL, *resolved = NULL, *joined = NULL;
                 const char *w;
                 bool ignore_enoent = false, shall_prefix = false;
 
-                r = extract_first_word(&cur, &word, NULL, EXTRACT_QUOTES);
+                r = extract_first_word(&p, &word, NULL, EXTRACT_QUOTES);
                 if (r == 0)
                         break;
                 if (r == -ENOMEM)
@@ -4141,7 +4121,7 @@ int config_parse_namespace_path_strv(
 
                 r = unit_full_printf(u, w, &resolved);
                 if (r < 0) {
-                        log_syntax(unit, LOG_ERR, filename, line, r, "Failed to resolve specifiers in %s: %m", word);
+                        log_syntax(unit, LOG_ERR, filename, line, r, "Failed to resolve unit specifiers in %s: %m", w);
                         continue;
                 }
 
@@ -4180,7 +4160,7 @@ int config_parse_temporary_filesystems(
 
         Unit *u = userdata;
         ExecContext *c = data;
-        const char *cur;
+        const char *p = rvalue;
         int r;
 
         assert(filename);
@@ -4196,14 +4176,13 @@ int config_parse_temporary_filesystems(
                 return 0;
         }
 
-        cur = rvalue;
         for (;;) {
                 _cleanup_free_ char *word = NULL, *path = NULL, *resolved = NULL;
                 const char *w;
 
-                r = extract_first_word(&cur, &word, NULL, EXTRACT_QUOTES);
+                r = extract_first_word(&p, &word, NULL, EXTRACT_QUOTES);
                 if (r == 0)
-                        break;
+                        return 0;
                 if (r == -ENOMEM)
                         return log_oom();
                 if (r < 0) {
@@ -4213,14 +4192,20 @@ int config_parse_temporary_filesystems(
 
                 w = word;
                 r = extract_first_word(&w, &path, ":", EXTRACT_DONT_COALESCE_SEPARATORS);
-                if (r < 0)
-                        return r;
-                if (r == 0)
-                        return -EINVAL;
+                if (r == -ENOMEM)
+                        return log_oom();
+                if (r < 0) {
+                        log_syntax(unit, LOG_ERR, filename, line, r, "Failed to extract first word, ignoring: %s", word);
+                        continue;
+                }
+                if (r == 0) {
+                        log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid syntax, ignoring: %s", word);
+                        continue;
+                }
 
                 r = unit_full_printf(u, path, &resolved);
                 if (r < 0) {
-                        log_syntax(unit, LOG_ERR, filename, line, r, "Failed to resolve specifiers in %s, ignoring: %m", word);
+                        log_syntax(unit, LOG_ERR, filename, line, r, "Failed to resolve unit specifiers in %s, ignoring: %m", path);
                         continue;
                 }
 
@@ -4239,8 +4224,6 @@ int config_parse_temporary_filesystems(
                         continue;
                 }
         }
-
-        return 0;
 }
 
 int config_parse_bind_paths(
@@ -4293,7 +4276,7 @@ int config_parse_bind_paths(
                 r = unit_full_printf(u, source, &sresolved);
                 if (r < 0) {
                         log_syntax(unit, LOG_ERR, filename, line, r,
-                                   "Failed to resolved specifiers in \"%s\", ignoring: %m", source);
+                                   "Failed to resolved unit specifiers in \"%s\", ignoring: %m", source);
                         return 0;
                 }
 
@@ -4398,20 +4381,20 @@ int config_parse_no_new_privileges(
                 void *userdata) {
 
         ExecContext *c = data;
-        int k;
+        int r;
 
         assert(filename);
         assert(lvalue);
         assert(rvalue);
         assert(data);
 
-        k = parse_boolean(rvalue);
-        if (k < 0) {
-                log_syntax(unit, LOG_ERR, filename, line, k, "Failed to parse boolean value, ignoring: %s", rvalue);
+        r = parse_boolean(rvalue);
+        if (r < 0) {
+                log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse boolean value, ignoring: %s", rvalue);
                 return 0;
         }
 
-        c->no_new_privileges = k;
+        c->no_new_privileges = r;
 
         return 0;
 }
@@ -4470,9 +4453,6 @@ int config_parse_protect_system(
         assert(rvalue);
         assert(data);
 
-        /* Our enum shall be a superset of booleans, hence first try
-         * to parse as boolean, and then as enum */
-
         s = parse_protect_system_or_bool(rvalue);
         if (s < 0) {
                 log_syntax(unit, LOG_ERR, filename, line, 0, "Failed to parse protect system value, ignoring: %s", rvalue);
@@ -4923,7 +4903,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..4bfe94398168c6081330a54591391258ffea30fe 100644 (file)
@@ -7,6 +7,7 @@
   Copyright 2010 Lennart Poettering
 ***/
 
+#include "conf-parser.h"
 #include "unit.h"
 
 /* Read service data from .desktop file style configuration fragments */
@@ -15,102 +16,101 @@ int unit_load_fragment(Unit *u);
 
 void unit_dump_config_items(FILE *f);
 
-int config_parse_unit_deps(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_obsolete_unit_deps(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
-int config_parse_unit_string_printf(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
-int config_parse_unit_strv_printf(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
-int config_parse_unit_path_printf(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
-int config_parse_unit_path_strv_printf(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
-int config_parse_documentation(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_socket_listen(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_socket_protocol(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_socket_bind(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_nice(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);
-int config_parse_exec(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_service_timeout(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_service_type(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_service_restart(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_socket_bindtodevice(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_output(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_input(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_input_text(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_input_data(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_io_class(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_io_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_exec_cpu_sched_policy(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_cpu_sched_prio(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_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);
-int config_parse_timer(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_trigger_unit(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_path_spec(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_socket_service(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_service_sockets(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
-int config_parse_unit_env_file(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_ip_tos(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
-int config_parse_unit_condition_path(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
-int config_parse_unit_condition_string(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
-int config_parse_unit_condition_null(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_mode(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
-int config_parse_notify_access(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_emergency_action(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
-int config_parse_unit_requires_mounts_for(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_syscall_archs(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_errno(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_environ(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_pass_environ(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_unset_environ(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
-int config_parse_unit_slice(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_weight(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_shares(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_memory_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_tasks_max(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_delegate(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_device_policy(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_device_allow(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_io_weight(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_io_device_weight(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_io_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_blockio_weight(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_blockio_device_weight(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_blockio_bandwidth(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_netclass(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_job_mode(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
-int config_parse_job_mode_isolate(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_selinux_context(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_apparmor_profile(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_smack_process_label(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_address_families(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_runtime_preserve_mode(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
-int config_parse_exec_directories(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_set_status(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_namespace_path_strv(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_temporary_filesystems(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_no_new_privileges(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_quota(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_protect_home(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_protect_system(const char* unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
-int config_parse_bus_name(const char* unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
-int config_parse_exec_utmp_mode(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
-int config_parse_working_directory(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
-int config_parse_fdname(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_sec_fix_0(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_user_group(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_user_group_strv(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_restrict_namespaces(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_bind_paths(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_keyring_mode(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
-int config_parse_job_timeout_sec(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_job_running_timeout_sec(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_log_extra_fields(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_collect_mode(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+CONFIG_PARSER_PROTOTYPE(config_parse_unit_deps);
+CONFIG_PARSER_PROTOTYPE(config_parse_obsolete_unit_deps);
+CONFIG_PARSER_PROTOTYPE(config_parse_unit_string_printf);
+CONFIG_PARSER_PROTOTYPE(config_parse_unit_strv_printf);
+CONFIG_PARSER_PROTOTYPE(config_parse_unit_path_printf);
+CONFIG_PARSER_PROTOTYPE(config_parse_unit_path_strv_printf);
+CONFIG_PARSER_PROTOTYPE(config_parse_documentation);
+CONFIG_PARSER_PROTOTYPE(config_parse_socket_listen);
+CONFIG_PARSER_PROTOTYPE(config_parse_socket_protocol);
+CONFIG_PARSER_PROTOTYPE(config_parse_socket_bind);
+CONFIG_PARSER_PROTOTYPE(config_parse_exec_nice);
+CONFIG_PARSER_PROTOTYPE(config_parse_exec_oom_score_adjust);
+CONFIG_PARSER_PROTOTYPE(config_parse_exec);
+CONFIG_PARSER_PROTOTYPE(config_parse_service_timeout);
+CONFIG_PARSER_PROTOTYPE(config_parse_service_type);
+CONFIG_PARSER_PROTOTYPE(config_parse_service_restart);
+CONFIG_PARSER_PROTOTYPE(config_parse_socket_bindtodevice);
+CONFIG_PARSER_PROTOTYPE(config_parse_exec_output);
+CONFIG_PARSER_PROTOTYPE(config_parse_exec_input);
+CONFIG_PARSER_PROTOTYPE(config_parse_exec_input_text);
+CONFIG_PARSER_PROTOTYPE(config_parse_exec_input_data);
+CONFIG_PARSER_PROTOTYPE(config_parse_exec_io_class);
+CONFIG_PARSER_PROTOTYPE(config_parse_exec_io_priority);
+CONFIG_PARSER_PROTOTYPE(config_parse_exec_cpu_sched_policy);
+CONFIG_PARSER_PROTOTYPE(config_parse_exec_cpu_sched_prio);
+CONFIG_PARSER_PROTOTYPE(config_parse_exec_cpu_affinity);
+CONFIG_PARSER_PROTOTYPE(config_parse_exec_secure_bits);
+CONFIG_PARSER_PROTOTYPE(config_parse_capability_set);
+CONFIG_PARSER_PROTOTYPE(config_parse_sysv_priority);
+CONFIG_PARSER_PROTOTYPE(config_parse_kill_signal);
+CONFIG_PARSER_PROTOTYPE(config_parse_exec_mount_flags);
+CONFIG_PARSER_PROTOTYPE(config_parse_timer);
+CONFIG_PARSER_PROTOTYPE(config_parse_trigger_unit);
+CONFIG_PARSER_PROTOTYPE(config_parse_path_spec);
+CONFIG_PARSER_PROTOTYPE(config_parse_socket_service);
+CONFIG_PARSER_PROTOTYPE(config_parse_service_sockets);
+CONFIG_PARSER_PROTOTYPE(config_parse_unit_env_file);
+CONFIG_PARSER_PROTOTYPE(config_parse_ip_tos);
+CONFIG_PARSER_PROTOTYPE(config_parse_unit_condition_path);
+CONFIG_PARSER_PROTOTYPE(config_parse_unit_condition_string);
+CONFIG_PARSER_PROTOTYPE(config_parse_unit_condition_null);
+CONFIG_PARSER_PROTOTYPE(config_parse_kill_mode);
+CONFIG_PARSER_PROTOTYPE(config_parse_notify_access);
+CONFIG_PARSER_PROTOTYPE(config_parse_emergency_action);
+CONFIG_PARSER_PROTOTYPE(config_parse_unit_requires_mounts_for);
+CONFIG_PARSER_PROTOTYPE(config_parse_syscall_filter);
+CONFIG_PARSER_PROTOTYPE(config_parse_syscall_archs);
+CONFIG_PARSER_PROTOTYPE(config_parse_syscall_errno);
+CONFIG_PARSER_PROTOTYPE(config_parse_environ);
+CONFIG_PARSER_PROTOTYPE(config_parse_pass_environ);
+CONFIG_PARSER_PROTOTYPE(config_parse_unset_environ);
+CONFIG_PARSER_PROTOTYPE(config_parse_unit_slice);
+CONFIG_PARSER_PROTOTYPE(config_parse_cpu_weight);
+CONFIG_PARSER_PROTOTYPE(config_parse_cpu_shares);
+CONFIG_PARSER_PROTOTYPE(config_parse_memory_limit);
+CONFIG_PARSER_PROTOTYPE(config_parse_tasks_max);
+CONFIG_PARSER_PROTOTYPE(config_parse_delegate);
+CONFIG_PARSER_PROTOTYPE(config_parse_device_policy);
+CONFIG_PARSER_PROTOTYPE(config_parse_device_allow);
+CONFIG_PARSER_PROTOTYPE(config_parse_io_weight);
+CONFIG_PARSER_PROTOTYPE(config_parse_io_device_weight);
+CONFIG_PARSER_PROTOTYPE(config_parse_io_limit);
+CONFIG_PARSER_PROTOTYPE(config_parse_blockio_weight);
+CONFIG_PARSER_PROTOTYPE(config_parse_blockio_device_weight);
+CONFIG_PARSER_PROTOTYPE(config_parse_blockio_bandwidth);
+CONFIG_PARSER_PROTOTYPE(config_parse_netclass);
+CONFIG_PARSER_PROTOTYPE(config_parse_job_mode);
+CONFIG_PARSER_PROTOTYPE(config_parse_job_mode_isolate);
+CONFIG_PARSER_PROTOTYPE(config_parse_exec_selinux_context);
+CONFIG_PARSER_PROTOTYPE(config_parse_exec_apparmor_profile);
+CONFIG_PARSER_PROTOTYPE(config_parse_exec_smack_process_label);
+CONFIG_PARSER_PROTOTYPE(config_parse_address_families);
+CONFIG_PARSER_PROTOTYPE(config_parse_runtime_preserve_mode);
+CONFIG_PARSER_PROTOTYPE(config_parse_exec_directories);
+CONFIG_PARSER_PROTOTYPE(config_parse_set_status);
+CONFIG_PARSER_PROTOTYPE(config_parse_namespace_path_strv);
+CONFIG_PARSER_PROTOTYPE(config_parse_temporary_filesystems);
+CONFIG_PARSER_PROTOTYPE(config_parse_no_new_privileges);
+CONFIG_PARSER_PROTOTYPE(config_parse_cpu_quota);
+CONFIG_PARSER_PROTOTYPE(config_parse_protect_home);
+CONFIG_PARSER_PROTOTYPE(config_parse_protect_system);
+CONFIG_PARSER_PROTOTYPE(config_parse_bus_name);
+CONFIG_PARSER_PROTOTYPE(config_parse_exec_utmp_mode);
+CONFIG_PARSER_PROTOTYPE(config_parse_working_directory);
+CONFIG_PARSER_PROTOTYPE(config_parse_fdname);
+CONFIG_PARSER_PROTOTYPE(config_parse_sec_fix_0);
+CONFIG_PARSER_PROTOTYPE(config_parse_user_group);
+CONFIG_PARSER_PROTOTYPE(config_parse_user_group_strv);
+CONFIG_PARSER_PROTOTYPE(config_parse_restrict_namespaces);
+CONFIG_PARSER_PROTOTYPE(config_parse_bind_paths);
+CONFIG_PARSER_PROTOTYPE(config_parse_exec_keyring_mode);
+CONFIG_PARSER_PROTOTYPE(config_parse_job_timeout_sec);
+CONFIG_PARSER_PROTOTYPE(config_parse_job_running_timeout_sec);
+CONFIG_PARSER_PROTOTYPE(config_parse_log_extra_fields);
+CONFIG_PARSER_PROTOTYPE(config_parse_collect_mode);
 
 /* gperf prototypes */
 const struct ConfigPerfItem* load_fragment_gperf_lookup(const char *key, GPERF_LEN_TYPE length);
index 42acb632931b150a66195c7234b3267b314df3cb..705dd95de1be46cff495698d995de80a7e7ff306 100644 (file)
@@ -97,8 +97,7 @@ int locale_setup(char ***environment) {
                         goto finish;
                 }
 
-                strv_free(*environment);
-                *environment = e;
+                strv_free_and_replace(*environment, e);
         }
 
         r = 0;
index 89fc68ceb3d47334290127ff95e3f604f869e6b6..f3b74f42739ca65da0bf0fce2a206b9d64f21355 100644 (file)
 %_udevhwdbdir @udevhwdbdir@
 %_udevrulesdir @udevrulesdir@
 %_journalcatalogdir @catalogdir@
-%_tmpfilesdir @tmpfilesdir@
-%_sysusersdir @sysusersdir@
-%_sysctldir @sysctldir@
 %_binfmtdir @binfmtdir@
+%_sysctldir @sysctldir@
+%_sysusersdir @sysusersdir@
+%_tmpfilesdir @tmpfilesdir@
+%_environmnentdir @environmentdir@
+%_modulesloaddir @modulesloaddir@
+%_modprobedir @modprobedir@
 %_systemdgeneratordir @systemgeneratordir@
 %_systemdusergeneratordir @usergeneratordir@
 %_systemd_system_env_generator_dir @systemenvgeneratordir@
@@ -38,23 +41,23 @@ OrderWithRequires(postun): systemd \
 %systemd_post() \
 if [ $1 -eq 1 ] ; then \
         # Initial installation \
-        systemctl --no-reload preset %{?*} >/dev/null 2>&1 || : \
+        systemctl --no-reload preset %{?*} &>/dev/null || : \
 fi \
 %{nil}
 
-%systemd_user_post() %{expand:%systemd_post \\--user \\--global %%{?*}}
+%systemd_user_post() %{expand:%systemd_post \\--global %%{?*}}
 
 %systemd_preun() \
 if [ $1 -eq 0 ] ; then \
         # Package removal, not upgrade \
-        systemctl --no-reload disable --now %{?*} > /dev/null 2>&1 || : \
+        systemctl --no-reload disable --now %{?*} &>/dev/null || : \
 fi \
 %{nil}
 
 %systemd_user_preun() \
 if [ $1 -eq 0 ] ; then \
         # Package removal, not upgrade \
-        systemctl --no-reload --user --global disable %{?*} > /dev/null 2>&1 || : \
+        systemctl --global disable %{?*} &>/dev/null || : \
 fi \
 %{nil}
 
@@ -65,7 +68,7 @@ fi \
 %systemd_postun_with_restart() \
 if [ $1 -ge 1 ] ; then \
         # Package upgrade, not uninstall \
-        systemctl try-restart %{?*} >/dev/null 2>&1 || : \
+        systemctl try-restart %{?*} &>/dev/null || : \
 fi \
 %{nil}
 
@@ -79,16 +82,16 @@ fi \
 
 # Deprecated. Use %tmpfiles_create_package instead
 %tmpfiles_create() \
-systemd-tmpfiles --create %{?*} >/dev/null 2>&1 || : \
+systemd-tmpfiles --create %{?*} &>/dev/null || : \
 %{nil}
 
 # Deprecated. Use %sysusers_create_package instead
 %sysusers_create() \
-systemd-sysusers %{?*} >/dev/null 2>&1 || : \
+systemd-sysusers %{?*} &>/dev/null || : \
 %{nil}
 
 %sysusers_create_inline() \
-systemd-sysusers - <<SYSTEMD_INLINE_EOF >/dev/null 2>&1 || : \
+systemd-sysusers - <<SYSTEMD_INLINE_EOF &>/dev/null || : \
 %{?*} \
 SYSTEMD_INLINE_EOF \
 %{nil}
@@ -107,7 +110,7 @@ SYSTEMD_INLINE_EOF \
 #   %files
 #   %{_sysusersdir}/%{name}.conf
 %sysusers_create_package() \
-systemd-sysusers --replace=%_sysusersdir/%1.conf - <<SYSTEMD_INLINE_EOF >/dev/null 2>&1 || : \
+systemd-sysusers --replace=%_sysusersdir/%1.conf - <<SYSTEMD_INLINE_EOF &>/dev/null || : \
 %(cat %2) \
 SYSTEMD_INLINE_EOF \
 %{nil}
@@ -126,15 +129,15 @@ SYSTEMD_INLINE_EOF \
 #   %files
 #   %{_tmpfilesdir}/%{name}.conf
 %tmpfiles_create_package() \
-systemd-tmpfiles --replace=%_tmpfilesdir/%1.conf --create - <<SYSTEMD_INLINE_EOF >/dev/null 2>&1 || : \
+systemd-tmpfiles --replace=%_tmpfilesdir/%1.conf --create - <<SYSTEMD_INLINE_EOF &>/dev/null || : \
 %(cat %2) \
 SYSTEMD_INLINE_EOF \
 %{nil}
 
 %sysctl_apply() \
-@rootlibexecdir@/systemd-sysctl %{?*} >/dev/null 2>&1 || : \
+@rootlibexecdir@/systemd-sysctl %{?*} &>/dev/null || : \
 %{nil}
 
 %binfmt_apply() \
-@rootlibexecdir@/systemd-binfmt %{?*} >/dev/null 2>&1 || : \
+@rootlibexecdir@/systemd-binfmt %{?*} &>/dev/null || : \
 %{nil}
index 201882ca95c029277c0bbceb181b4c94315f4319..d70c1b8160ec29b4963432b5080d3b71e2ac9c9e 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             },
@@ -1472,7 +1473,7 @@ static void initialize_clock(void) {
 }
 
 static void initialize_coredump(bool skip_setup) {
-
+#if ENABLE_COREDUMP
         if (getpid_cached() != 1)
                 return;
 
@@ -1485,6 +1486,7 @@ static void initialize_coredump(bool skip_setup) {
          * until the systemd-coredump tool is enabled via sysctl. */
         if (!skip_setup)
                 disable_coredumps();
+#endif
 }
 
 static void do_reexecute(
index 6412fee4764e215e85b6a6841c1a825fe541d1fc..b4f197c20498bb126a79694a476975ec24800a1c 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);
@@ -2337,7 +2338,7 @@ static void manager_handle_ctrl_alt_del(Manager *m) {
          * 7 times within 2s, we reboot/shutdown immediately,
          * unless it was disabled in system.conf */
 
-        if (ratelimit_test(&m->ctrl_alt_del_ratelimit) || m->cad_burst_action == EMERGENCY_ACTION_NONE)
+        if (ratelimit_below(&m->ctrl_alt_del_ratelimit) || m->cad_burst_action == EMERGENCY_ACTION_NONE)
                 manager_start_target(m, SPECIAL_CTRL_ALT_DEL_TARGET, JOB_REPLACE_IRREVERSIBLY);
         else
                 emergency_action(m, m->cad_burst_action, NULL,
@@ -2632,7 +2633,7 @@ int manager_loop(Manager *m) {
                 if (m->runtime_watchdog > 0 && m->runtime_watchdog != USEC_INFINITY && MANAGER_IS_SYSTEM(m))
                         watchdog_ping();
 
-                if (!ratelimit_test(&rl)) {
+                if (!ratelimit_below(&rl)) {
                         /* Yay, something is going seriously wrong, pause a little */
                         log_warning("Looping too fast. Throttling execution a little.");
                         sleep(1);
@@ -2696,12 +2697,19 @@ int manager_load_unit_from_dbus_path(Manager *m, const char *s, sd_bus_error *e,
                         return 0;
                 }
 
-                return sd_bus_error_setf(e, BUS_ERROR_NO_UNIT_FOR_INVOCATION_ID, "No unit with the specified invocation ID " SD_ID128_FORMAT_STR " known.", SD_ID128_FORMAT_VAL(invocation_id));
+                return sd_bus_error_setf(e, BUS_ERROR_NO_UNIT_FOR_INVOCATION_ID,
+                                         "No unit with the specified invocation ID " SD_ID128_FORMAT_STR " known.",
+                                         SD_ID128_FORMAT_VAL(invocation_id));
         }
 
         /* If this didn't work, we check if this is a unit name */
-        if (!unit_name_is_valid(n, UNIT_NAME_PLAIN|UNIT_NAME_INSTANCE))
-                return sd_bus_error_setf(e, SD_BUS_ERROR_INVALID_ARGS, "Unit name %s is neither a valid invocation ID nor unit name.", n);
+        if (!unit_name_is_valid(n, UNIT_NAME_PLAIN|UNIT_NAME_INSTANCE)) {
+                _cleanup_free_ char *nn = NULL;
+
+                nn = cescape(n);
+                return sd_bus_error_setf(e, SD_BUS_ERROR_INVALID_ARGS,
+                                         "Unit name %s is neither a valid invocation ID nor unit name.", strnull(nn));
+        }
 
         r = manager_load_unit(m, n, NULL, e, &u);
         if (r < 0)
@@ -3178,6 +3186,17 @@ finish:
         return r;
 }
 
+static void manager_flush_finished_jobs(Manager *m) {
+        Job *j;
+
+        while ((j = set_steal_first(m->pending_finished_jobs))) {
+                bus_job_send_removed_signal(j);
+                job_free(j);
+        }
+
+        m->pending_finished_jobs = set_free(m->pending_finished_jobs);
+}
+
 int manager_reload(Manager *m) {
         int r, q;
         _cleanup_fclose_ FILE *f = NULL;
@@ -3286,6 +3305,9 @@ int manager_reload(Manager *m) {
         if (q < 0 && r >= 0)
                 r = q;
 
+        if (!MANAGER_IS_RELOADING(m))
+                manager_flush_finished_jobs(m);
+
         m->send_reloading_done = true;
 
         return r;
index 35a3a1eb4000320573b43085ff03a9f7b128e888..1f97c15365c83e23edfa9dd5063d6cfb2d93cb52 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 */
@@ -299,6 +300,9 @@ struct Manager {
 
         /* non-zero if we are reloading or reexecuting, */
         int n_reloading;
+        /* A set which contains all jobs that started before reload and finished
+         * during it */
+        Set *pending_finished_jobs;
 
         unsigned n_installed_jobs;
         unsigned n_failed_jobs;
index e4b0a148098de1ff25e10fb8aebe8c40c4e19b8d..9df8c20a0ebc15ca326ee92eeb341b34ccbcceb7 100644 (file)
@@ -127,7 +127,7 @@ load_fragment_gperf_gperf = custom_target(
         'load-fragment-gperf.gperf',
         input : 'load-fragment-gperf.gperf.m4',
         output: 'load-fragment-gperf.gperf',
-        command : [m4, '-P'] + m4_defines + ['@INPUT@'],
+        command : [meson_apply_m4, config_h, '@INPUT@'],
         capture : true)
 
 load_fragment_gperf_c = custom_target(
index ac2412bf538f6ef954da22232505d5e5f824839f..e9d69728fad22c49d756b098729417725d0980c0 100644 (file)
@@ -279,7 +279,7 @@ int mount_cgroup_controllers(char ***join_controllers) {
                         if (strv_find(*k, controller))
                                 break;
 
-                if (k && *k) {
+                if (*k) {
                         char **i, **j;
 
                         for (i = *k, j = *k; *i; i++) {
@@ -317,7 +317,7 @@ int mount_cgroup_controllers(char ***join_controllers) {
                 if (r < 0)
                         return r;
 
-                if (r > 0 && k && *k) {
+                if (r > 0 && *k) {
                         char **i;
 
                         for (i = *k; *i; i++) {
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 4a7fea920ec32fa53b3e891b25bc79c0f1db0456..3154cad58a17e88211b6f26da5040eef7f1ff216 100644 (file)
@@ -81,23 +81,26 @@ static const MountEntry apivfs_table[] = {
 
 /* ProtectKernelTunables= option and the related filesystem APIs */
 static const MountEntry protect_kernel_tunables_table[] = {
-        { "/proc/sys",           READONLY,     false },
-        { "/proc/sysrq-trigger", READONLY,     true  },
-        { "/proc/latency_stats", READONLY,     true  },
-        { "/proc/mtrr",          READONLY,     true  },
-        { "/proc/apm",           READONLY,     true  }, /* Obsolete API, there's no point in permitting access to this, ever */
         { "/proc/acpi",          READONLY,     true  },
-        { "/proc/timer_stats",   READONLY,     true  },
+        { "/proc/apm",           READONLY,     true  }, /* Obsolete API, there's no point in permitting access to this, ever */
         { "/proc/asound",        READONLY,     true  },
         { "/proc/bus",           READONLY,     true  },
         { "/proc/fs",            READONLY,     true  },
         { "/proc/irq",           READONLY,     true  },
+        { "/proc/kallsyms",      INACCESSIBLE, true  },
+        { "/proc/kcore",         INACCESSIBLE, true  },
+        { "/proc/latency_stats", READONLY,     true  },
+        { "/proc/mtrr",          READONLY,     true  },
+        { "/proc/scsi",          READONLY,     true  },
+        { "/proc/sys",           READONLY,     false },
+        { "/proc/sysrq-trigger", READONLY,     true  },
+        { "/proc/timer_stats",   READONLY,     true  },
         { "/sys",                READONLY,     false },
-        { "/sys/kernel/debug",   READONLY,     true  },
-        { "/sys/kernel/tracing", READONLY,     true  },
         { "/sys/fs/bpf",         READONLY,     true  },
         { "/sys/fs/cgroup",      READWRITE,    false }, /* READONLY is set by ProtectControlGroups= option */
         { "/sys/fs/selinux",     READWRITE,    true  },
+        { "/sys/kernel/debug",   READONLY,     true  },
+        { "/sys/kernel/tracing", READONLY,     true  },
 };
 
 /* ProtectKernelModules= option */
index 0114128a5734f774012f7d7cd845152de3cfc92b..415b3f5d84f8759e0cd903412828b51d2c9a836c 100644 (file)
                        send_interface="org.freedesktop.systemd1.Manager"
                        send_member="Dump"/>
 
+                <allow send_destination="org.freedesktop.systemd1"
+                       send_interface="org.freedesktop.systemd1.Manager"
+                       send_member="DumpByFileDescriptor"/>
+
                 <allow send_destination="org.freedesktop.systemd1"
                        send_interface="org.freedesktop.systemd1.Manager"
                        send_member="ListUnitFiles"/>
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 15a7c13149df31215238f465930c56ffe54aceec..45c49eac49da1196fd0208577889adaf0442e813 100644 (file)
@@ -2245,7 +2245,7 @@ static void socket_enter_running(Socket *s, int cfd) {
                 return;
         }
 
-        if (!ratelimit_test(&s->trigger_limit)) {
+        if (!ratelimit_below(&s->trigger_limit)) {
                 safe_close(cfd);
                 log_unit_warning(UNIT(s), "Trigger limit hit, refusing further activation.");
                 socket_enter_stop_pre(s, SOCKET_FAILURE_TRIGGER_LIMIT_HIT);
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 4d9f4df6edac55d12bbd81e1db59375699217bd4..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"
@@ -1240,7 +1241,7 @@ static Unit *swap_following(Unit *u) {
 
 static int swap_following_set(Unit *u, Set **_set) {
         Swap *s = SWAP(u), *other;
-        Set *set;
+        _cleanup_set_free_ Set *set = NULL;
         int r;
 
         assert(s);
@@ -1258,15 +1259,11 @@ static int swap_following_set(Unit *u, Set **_set) {
         LIST_FOREACH_OTHERS(same_devnode, other, s) {
                 r = set_put(set, other);
                 if (r < 0)
-                        goto fail;
+                        return r;
         }
 
-        *_set = set;
+        *_set = TAKE_PTR(set);
         return 1;
-
-fail:
-        set_free(set);
-        return r;
 }
 
 static void swap_shutdown(Manager *m) {
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 09ed43a104c5104ba4dfb46a7b449c29caa39481..2567365937f5dc13705e245dda46fec1498e3c3e 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"
@@ -1695,7 +1696,7 @@ void unit_status_emit_starting_stopping_reloading(Unit *u, JobType t) {
 int unit_start_limit_test(Unit *u) {
         assert(u);
 
-        if (ratelimit_test(&u->start_limit)) {
+        if (ratelimit_below(&u->start_limit)) {
                 u->start_limit_hit = false;
                 return 0;
         }
@@ -1988,7 +1989,7 @@ static void unit_check_unneeded(Unit *u) {
         /* If stopping a unit fails continuously we might enter a stop
          * loop here, hence stop acting on the service being
          * unnecessary after a while. */
-        if (!ratelimit_test(&u->auto_stop_ratelimit)) {
+        if (!ratelimit_below(&u->auto_stop_ratelimit)) {
                 log_unit_warning(u, "Unit not needed anymore, but not stopping since we tried this too often recently.");
                 return;
         }
@@ -2038,7 +2039,7 @@ static void unit_check_binds_to(Unit *u) {
         /* If stopping a unit fails continuously we might enter a stop
          * loop here, hence stop acting on the service being
          * unnecessary after a while. */
-        if (!ratelimit_test(&u->auto_stop_ratelimit)) {
+        if (!ratelimit_below(&u->auto_stop_ratelimit)) {
                 log_unit_warning(u, "Unit is bound to inactive unit %s, but not stopping since we tried this too often recently.", other->id);
                 return;
         }
@@ -3815,7 +3816,7 @@ int unit_kill(Unit *u, KillWho w, int signo, sd_bus_error *error) {
 }
 
 static Set *unit_pid_set(pid_t main_pid, pid_t control_pid) {
-        Set *pid_set;
+        _cleanup_set_free_ Set *pid_set = NULL;
         int r;
 
         pid_set = set_new(NULL);
@@ -3826,20 +3827,16 @@ static Set *unit_pid_set(pid_t main_pid, pid_t control_pid) {
         if (main_pid > 0) {
                 r = set_put(pid_set, PID_TO_PTR(main_pid));
                 if (r < 0)
-                        goto fail;
+                        return NULL;
         }
 
         if (control_pid > 0) {
                 r = set_put(pid_set, PID_TO_PTR(control_pid));
                 if (r < 0)
-                        goto fail;
+                        return NULL;
         }
 
-        return pid_set;
-
-fail:
-        set_free(pid_set);
-        return NULL;
+        return TAKE_PTR(pid_set);
 }
 
 int unit_kill_common(
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 e255206228aafee9d3b9f0007d0bdd24127acd3f..2933a449db0d8045b275ba564c7c5c7b5903183c 100644 (file)
@@ -217,7 +217,7 @@ static int parse_argv(int argc, char *argv[]) {
 
                 case 'o':
                         if (arg_output) {
-                                log_error("cannot set output more than once");
+                                log_error("Cannot set output more than once.");
                                 return -EINVAL;
                         }
 
@@ -241,7 +241,7 @@ static int parse_argv(int argc, char *argv[]) {
 
                 case 'F':
                         if (arg_field) {
-                                log_error("cannot use --field/-F more than once");
+                                log_error("Cannot use --field/-F more than once.");
                                 return -EINVAL;
                         }
                         arg_field = optarg;
index 3fbcdf555638f85b9d14f461ca1fe82274d34e0b..197e526b0565ef2cbd29e3a7f622830271b5e1eb 100644 (file)
@@ -10,6 +10,7 @@
 #include <stdbool.h>
 #include <stdlib.h>
 
+#include "string-table.h"
 #include "util.h"
 #include "virt.h"
 
@@ -32,6 +33,7 @@ static void help(void) {
                "  -r --chroot           Detect whether we are run in a chroot() environment\n"
                "     --private-users    Only detect whether we are running in a user namespace\n"
                "  -q --quiet            Don't output anything, just set return value\n"
+               "     --list             List all known and detectable types of virtualization\n"
                , program_invocation_short_name);
 }
 
@@ -40,6 +42,7 @@ static int parse_argv(int argc, char *argv[]) {
         enum {
                 ARG_VERSION = 0x100,
                 ARG_PRIVATE_USERS,
+                ARG_LIST,
         };
 
         static const struct option options[] = {
@@ -50,6 +53,7 @@ static int parse_argv(int argc, char *argv[]) {
                 { "chroot",        no_argument, NULL, 'r'               },
                 { "private-users", no_argument, NULL, ARG_PRIVATE_USERS },
                 { "quiet",         no_argument, NULL, 'q'               },
+                { "list",          no_argument, NULL, ARG_LIST          },
                 {}
         };
 
@@ -89,6 +93,10 @@ static int parse_argv(int argc, char *argv[]) {
                         arg_mode = ONLY_CHROOT;
                         break;
 
+                case ARG_LIST:
+                        DUMP_STRING_TABLE(virtualization, int, _VIRTUALIZATION_MAX);
+                        return 0;
+
                 case '?':
                         return -EINVAL;
 
index ce3733930712e971c0cf6d8a4be2496650facae6..7895e3832aa0516f1e92ac1b538fecaafcd6a456 100644 (file)
@@ -364,6 +364,10 @@ static int process_keymap(void) {
         return 0;
 }
 
+static bool timezone_is_valid_log_error(const char *name) {
+        return timezone_is_valid(name, LOG_ERR);
+}
+
 static int prompt_timezone(void) {
         _cleanup_strv_free_ char **zones = NULL;
         int r;
@@ -387,7 +391,7 @@ static int prompt_timezone(void) {
 
         putchar('\n');
 
-        r = prompt_loop("Please enter timezone name or number", zones, timezone_is_valid, &arg_timezone);
+        r = prompt_loop("Please enter timezone name or number", zones, timezone_is_valid_log_error, &arg_timezone);
         if (r < 0)
                 return r;
 
@@ -827,7 +831,7 @@ static int parse_argv(int argc, char *argv[]) {
                         break;
 
                 case ARG_TIMEZONE:
-                        if (!timezone_is_valid(optarg)) {
+                        if (!timezone_is_valid(optarg, LOG_ERR)) {
                                 log_error("Timezone %s is not valid.", optarg);
                                 return -EINVAL;
                         }
index d9ad2fb2fe4a658583c5d74c64784350a1845f4a..88a8938c311d7d670c342698caac1ede5dcbd9b0 100644 (file)
@@ -338,8 +338,7 @@ static int context_write_data_machine_info(Context *c) {
                 if (!u)
                         return -ENOMEM;
 
-                strv_free(l);
-                l = u;
+                strv_free_and_replace(l, u);
         }
 
         if (strv_isempty(l)) {
@@ -400,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);
@@ -436,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) {
@@ -474,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,
@@ -488,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) {
@@ -540,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... */
@@ -558,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 2ae146fd324538d90c282bfff8dc49178bef3205..c9070acf2020da48c9b90ffe901cfc600aac9fd2 100644 (file)
@@ -126,7 +126,7 @@ static void raw_export_report_progress(RawExport *e) {
         if (percent == e->last_percent)
                 return;
 
-        if (!ratelimit_test(&e->progress_rate_limit))
+        if (!ratelimit_below(&e->progress_rate_limit))
                 return;
 
         sd_notifyf(false, "X_IMPORT_PROGRESS=%u", percent);
index 72c48c68d7eafabdf1eeea8135b35d4a3c308841..4c60854972f94e56c7da4ae94c76acb935d98b61 100644 (file)
@@ -134,7 +134,7 @@ static void tar_export_report_progress(TarExport *e) {
         if (percent == e->last_percent)
                 return;
 
-        if (!ratelimit_test(&e->progress_rate_limit))
+        if (!ratelimit_below(&e->progress_rate_limit))
                 return;
 
         sd_notifyf(false, "X_IMPORT_PROGRESS=%u", percent);
index 6b79d8f170252b2be0060d7f0a8b4d8f590a0872..02ff289c1a877ee3306ba7c9fc9ac96fcfee0d92 100644 (file)
@@ -149,7 +149,7 @@ static void raw_import_report_progress(RawImport *i) {
         if (percent == i->last_percent)
                 return;
 
-        if (!ratelimit_test(&i->progress_rate_limit))
+        if (!ratelimit_below(&i->progress_rate_limit))
                 return;
 
         sd_notifyf(false, "X_IMPORT_PROGRESS=%u", percent);
index 81b96662d334bea6e17b2ce172a0f868c01fa2c9..2e748c629d1ab9cb609489710347de500e51e991 100644 (file)
@@ -156,7 +156,7 @@ static void tar_import_report_progress(TarImport *i) {
         if (percent == i->last_percent)
                 return;
 
-        if (!ratelimit_test(&i->progress_rate_limit))
+        if (!ratelimit_below(&i->progress_rate_limit))
                 return;
 
         sd_notifyf(false, "X_IMPORT_PROGRESS=%u", percent);
index 9c13d7b46d6b879068047962279eccce3c742c4c..24bf427103a39ac233acd470820290c4c4ec7978 100644 (file)
@@ -448,7 +448,7 @@ error:
 int catalog_update(const char* database, const char* root, const char* const* dirs) {
         _cleanup_strv_free_ char **files = NULL;
         char **f;
-        struct strbuf *sb = NULL;
+        _cleanup_(strbuf_cleanupp) struct strbuf *sb = NULL;
         _cleanup_hashmap_free_free_free_ Hashmap *h = NULL;
         _cleanup_free_ CatalogItem *items = NULL;
         ssize_t offset;
@@ -461,38 +461,29 @@ int catalog_update(const char* database, const char* root, const char* const* di
 
         h = hashmap_new(&catalog_hash_ops);
         sb = strbuf_new();
-
-        if (!h || !sb) {
-                r = log_oom();
-                goto finish;
-        }
+        if (!h || !sb)
+                return log_oom();
 
         r = conf_files_list_strv(&files, ".catalog", root, 0, dirs);
-        if (r < 0) {
-                log_error_errno(r, "Failed to get catalog files: %m");
-                goto finish;
-        }
+        if (r < 0)
+                return log_error_errno(r, "Failed to get catalog files: %m");
 
         STRV_FOREACH(f, files) {
                 log_debug("Reading file '%s'", *f);
                 r = catalog_import_file(h, *f);
-                if (r < 0) {
-                        log_error_errno(r, "Failed to import file '%s': %m", *f);
-                        goto finish;
-                }
+                if (r < 0)
+                        return log_error_errno(r, "Failed to import file '%s': %m", *f);
         }
 
         if (hashmap_size(h) <= 0) {
                 log_info("No items in catalog.");
-                goto finish;
+                return 0;
         } else
                 log_debug("Found %u items in catalog.", hashmap_size(h));
 
         items = new(CatalogItem, hashmap_size(h));
-        if (!items) {
-                r = log_oom();
-                goto finish;
-        }
+        if (!items)
+                return log_oom();
 
         n = 0;
         HASHMAP_FOREACH_KEY(payload, i, h, j) {
@@ -501,10 +492,9 @@ int catalog_update(const char* database, const char* root, const char* const* di
                           isempty(i->language) ? "C" : i->language);
 
                 offset = strbuf_add_string(sb, payload, strlen(payload));
-                if (offset < 0) {
-                        r = log_oom();
-                        goto finish;
-                }
+                if (offset < 0)
+                        return log_oom();
+
                 i->offset = htole64((uint64_t) offset);
                 items[n++] = *i;
         }
@@ -516,17 +506,11 @@ int catalog_update(const char* database, const char* root, const char* const* di
 
         sz = write_catalog(database, sb, items, n);
         if (sz < 0)
-                r = log_error_errno(sz, "Failed to write %s: %m", database);
-        else {
-                r = 0;
-                log_debug("%s: wrote %u items, with %zu bytes of strings, %"PRIi64" total size.",
-                          database, n, sb->len, sz);
-        }
-
-finish:
-        strbuf_cleanup(sb);
+                return log_error_errno(sz, "Failed to write %s: %m", database);
 
-        return r;
+        log_debug("%s: wrote %u items, with %zu bytes of strings, %"PRIi64" total size.",
+                  database, n, sb->len, sz);
+        return 0;
 }
 
 static int open_mmap(const char *database, int *_fd, struct stat *_st, void **_p) {
index aa59489cff6673e970dfde1d3a2ce41fca6982a7..92cf2eb1228f95671659205a734beb5a953bd428 100644 (file)
 #include "rlimit-util.h"
 #include "set.h"
 #include "sigbus.h"
+#include "string-table.h"
 #include "strv.h"
 #include "syslog-util.h"
 #include "terminal-util.h"
-#include "udev.h"
 #include "udev-util.h"
+#include "udev.h"
 #include "unit-name.h"
 #include "user-util.h"
 
@@ -509,6 +510,11 @@ static int parse_argv(int argc, char *argv[]) {
                         break;
 
                 case 'o':
+                        if (streq(optarg, "help")) {
+                                DUMP_STRING_TABLE(output_mode, OutputMode, _OUTPUT_MODE_MAX);
+                                return 0;
+                        }
+
                         arg_output = output_mode_from_string(optarg);
                         if (arg_output < 0) {
                                 log_error("Unknown output format '%s'.", optarg);
index 6d01b2da3de1471b059bf0e4e3e89a67a07ef6b1..2728ac11690b21de7776891a9ba58dd81c781bc8 100644 (file)
@@ -14,6 +14,7 @@
 
 typedef struct Server Server;
 
+#include "conf-parser.h"
 #include "hashmap.h"
 #include "journal-file.h"
 #include "journald-context.h"
@@ -195,14 +196,14 @@ void server_driver_message(Server *s, pid_t object_pid, const char *message_id,
 /* gperf lookup function */
 const struct ConfigPerfItem* journald_gperf_lookup(const char *key, GPERF_LEN_TYPE length);
 
-int config_parse_storage(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_line_max(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_compress(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);
+CONFIG_PARSER_PROTOTYPE(config_parse_storage);
+CONFIG_PARSER_PROTOTYPE(config_parse_line_max);
+CONFIG_PARSER_PROTOTYPE(config_parse_compress);
 
 const char *storage_to_string(Storage s) _const_;
 Storage storage_from_string(const char *s) _pure_;
 
-int config_parse_split_mode(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+CONFIG_PARSER_PROTOTYPE(config_parse_split_mode);
 
 const char *split_mode_to_string(SplitMode s) _const_;
 SplitMode split_mode_from_string(const char *s) _pure_;
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 f96d898b2df40ae0a973f3b1b38098b62854c6ba..2e81799add17ed5081a9e5b9039dd22d1a6616d8 100644 (file)
@@ -1814,7 +1814,7 @@ static int allocate_inotify(sd_journal *j) {
 }
 
 static sd_journal *journal_new(int flags, const char *path) {
-        sd_journal *j;
+        _cleanup_(sd_journal_closep) sd_journal *j = NULL;
 
         j = new0(sd_journal, 1);
         if (!j)
@@ -1831,7 +1831,7 @@ static sd_journal *journal_new(int flags, const char *path) {
 
                 t = strdup(path);
                 if (!t)
-                        goto fail;
+                        return NULL;
 
                 if (flags & SD_JOURNAL_OS_ROOT)
                         j->prefix = t;
@@ -1841,19 +1841,15 @@ static sd_journal *journal_new(int flags, const char *path) {
 
         j->files = ordered_hashmap_new(&path_hash_ops);
         if (!j->files)
-                goto fail;
+                return NULL;
 
         j->files_cache = ordered_hashmap_iterated_cache_new(j->files);
         j->directories_by_path = hashmap_new(&path_hash_ops);
         j->mmap = mmap_cache_new();
         if (!j->files_cache || !j->directories_by_path || !j->mmap)
-                goto fail;
-
-        return j;
+                return NULL;
 
-fail:
-        sd_journal_close(j);
-        return NULL;
+        return TAKE_PTR(j);
 }
 
 #define OPEN_ALLOWED_FLAGS                              \
@@ -1862,7 +1858,7 @@ fail:
          SD_JOURNAL_SYSTEM | SD_JOURNAL_CURRENT_USER)
 
 _public_ int sd_journal_open(sd_journal **ret, int flags) {
-        sd_journal *j;
+        _cleanup_(sd_journal_closep) sd_journal *j = NULL;
         int r;
 
         assert_return(ret, -EINVAL);
@@ -1874,15 +1870,10 @@ _public_ int sd_journal_open(sd_journal **ret, int flags) {
 
         r = add_search_paths(j);
         if (r < 0)
-                goto fail;
+                return r;
 
-        *ret = j;
+        *ret = TAKE_PTR(j);
         return 0;
-
-fail:
-        sd_journal_close(j);
-
-        return r;
 }
 
 #define OPEN_CONTAINER_ALLOWED_FLAGS                    \
@@ -1890,7 +1881,7 @@ fail:
 
 _public_ int sd_journal_open_container(sd_journal **ret, const char *machine, int flags) {
         _cleanup_free_ char *root = NULL, *class = NULL;
-        sd_journal *j;
+        _cleanup_(sd_journal_closep) sd_journal *j = NULL;
         char *p;
         int r;
 
@@ -1920,14 +1911,10 @@ _public_ int sd_journal_open_container(sd_journal **ret, const char *machine, in
 
         r = add_search_paths(j);
         if (r < 0)
-                goto fail;
+                return r;
 
-        *ret = j;
+        *ret = TAKE_PTR(j);
         return 0;
-
-fail:
-        sd_journal_close(j);
-        return r;
 }
 
 #define OPEN_DIRECTORY_ALLOWED_FLAGS                    \
@@ -1935,7 +1922,7 @@ fail:
          SD_JOURNAL_SYSTEM | SD_JOURNAL_CURRENT_USER )
 
 _public_ int sd_journal_open_directory(sd_journal **ret, const char *path, int flags) {
-        sd_journal *j;
+        _cleanup_(sd_journal_closep) sd_journal *j = NULL;
         int r;
 
         assert_return(ret, -EINVAL);
@@ -1951,18 +1938,14 @@ _public_ int sd_journal_open_directory(sd_journal **ret, const char *path, int f
         else
                 r = add_root_directory(j, path, false);
         if (r < 0)
-                goto fail;
+                return r;
 
-        *ret = j;
+        *ret = TAKE_PTR(j);
         return 0;
-
-fail:
-        sd_journal_close(j);
-        return r;
 }
 
 _public_ int sd_journal_open_files(sd_journal **ret, const char **paths, int flags) {
-        sd_journal *j;
+        _cleanup_(sd_journal_closep) sd_journal *j = NULL;
         const char **path;
         int r;
 
@@ -1976,17 +1959,13 @@ _public_ int sd_journal_open_files(sd_journal **ret, const char **paths, int fla
         STRV_FOREACH(path, paths) {
                 r = add_any_file(j, -1, *path);
                 if (r < 0)
-                        goto fail;
+                        return r;
         }
 
         j->no_new_files = true;
 
-        *ret = j;
+        *ret = TAKE_PTR(j);
         return 0;
-
-fail:
-        sd_journal_close(j);
-        return r;
 }
 
 #define OPEN_DIRECTORY_FD_ALLOWED_FLAGS         \
@@ -1994,7 +1973,7 @@ fail:
          SD_JOURNAL_SYSTEM | SD_JOURNAL_CURRENT_USER )
 
 _public_ int sd_journal_open_directory_fd(sd_journal **ret, int fd, int flags) {
-        sd_journal *j;
+        _cleanup_(sd_journal_closep) sd_journal *j = NULL;
         struct stat st;
         int r;
 
@@ -2019,20 +1998,16 @@ _public_ int sd_journal_open_directory_fd(sd_journal **ret, int fd, int flags) {
         else
                 r = add_root_directory(j, NULL, false);
         if (r < 0)
-                goto fail;
+                return r;
 
-        *ret = j;
+        *ret = TAKE_PTR(j);
         return 0;
-
-fail:
-        sd_journal_close(j);
-        return r;
 }
 
 _public_ int sd_journal_open_files_fd(sd_journal **ret, int fds[], unsigned n_fds, int flags) {
         Iterator iterator;
         JournalFile *f;
-        sd_journal *j;
+        _cleanup_(sd_journal_closep) sd_journal *j = NULL;
         unsigned i;
         int r;
 
@@ -2069,7 +2044,7 @@ _public_ int sd_journal_open_files_fd(sd_journal **ret, int fds[], unsigned n_fd
         j->no_new_files = true;
         j->no_inotify = true;
 
-        *ret = j;
+        *ret = TAKE_PTR(j);
         return 0;
 
 fail:
@@ -2078,7 +2053,6 @@ fail:
         ORDERED_HASHMAP_FOREACH(f, j->files, iterator)
                 f->close_fd = false;
 
-        sd_journal_close(j);
         return r;
 }
 
index 9e3476d405e617f0841e2627aef990cdf89e6a4f..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,29 +161,21 @@ 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);
+        assert_se(r == 0);
 
         /* Test what happens if there are no files in the directory. */
         r = catalog_update(database, NULL, no_catalog_dirs);
-        assert_se(r >= 0);
+        assert_se(r == 0);
 
         /* Make sure that we at least have some files loaded or the
            catalog_list below will fail. */
         r = catalog_update(database, NULL, catalog_dirs);
-        assert_se(r >= 0);
+        assert_se(r == 0);
 }
 
 static void test_catalog_file_lang(void) {
@@ -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 c95597a00bbe05ed4249a0fee05fa969d299aeec..4832ee6a2cd95d47389426a830bf653b02cb8472 100644 (file)
@@ -12,6 +12,7 @@
 
 #include "alloc-util.h"
 #include "utf8.h"
+#include "strv.h"
 
 #include "dhcp-internal.h"
 
@@ -35,6 +36,34 @@ static int option_append(uint8_t options[], size_t size, size_t *offset,
                 *offset += 1;
                 break;
 
+        case SD_DHCP_OPTION_USER_CLASS: {
+                size_t len = 0;
+                char **s;
+
+                STRV_FOREACH(s, (char **) optval)
+                        len += strlen(*s) + 1;
+
+                if (size < *offset + len + 2)
+                        return -ENOBUFS;
+
+                options[*offset] = code;
+                options[*offset + 1] =  len;
+                *offset += 2;
+
+                STRV_FOREACH(s, (char **) optval) {
+                        len = strlen(*s);
+
+                        if (len > 255)
+                                return -ENAMETOOLONG;
+
+                        options[*offset] = len;
+
+                        memcpy_safe(&options[*offset + 1], *s, len);
+                        *offset += len + 1;
+                }
+
+                break;
+        }
         default:
                 if (size < *offset + optlen + 2)
                         return -ENOBUFS;
index 620f7115456d8e0263ca956c1fb3c98a2837c7e8..f2acb281f5a5e7d9cb04db65894d072a63d28547 100644 (file)
@@ -97,7 +97,7 @@ static bool net_condition_test_strv(char * const *raw_patterns,
         return string && strv_fnmatch(raw_patterns, string, 0);
 }
 
-bool net_match_config(const struct ether_addr *match_mac,
+bool net_match_config(Set *match_mac,
                       char * const *match_paths,
                       char * const *match_drivers,
                       char * const *match_types,
@@ -129,7 +129,7 @@ bool net_match_config(const struct ether_addr *match_mac,
         if (match_arch && condition_test(match_arch) <= 0)
                 return false;
 
-        if (match_mac && (!dev_mac || memcmp(match_mac, dev_mac, ETH_ALEN)))
+        if (match_mac && dev_mac && !set_contains(match_mac, dev_mac))
                 return false;
 
         if (!net_condition_test_strv(match_paths, dev_path))
@@ -281,10 +281,9 @@ int config_parse_hwaddr(const char *unit,
                         const char *rvalue,
                         void *data,
                         void *userdata) {
+
+        _cleanup_free_ struct ether_addr *n = NULL;
         struct ether_addr **hwaddr = data;
-        struct ether_addr *n;
-        const char *start;
-        size_t offset;
         int r;
 
         assert(filename);
@@ -296,17 +295,86 @@ int config_parse_hwaddr(const char *unit,
         if (!n)
                 return log_oom();
 
-        start = rvalue + strspn(rvalue, WHITESPACE);
-        r = ether_addr_from_string(start, n, &offset);
+        r = ether_addr_from_string(rvalue, n);
+        if (r < 0) {
+                log_syntax(unit, LOG_ERR, filename, line, r, "Not a valid MAC address, ignoring assignment: %s", rvalue);
+                return 0;
+        }
+
+        *hwaddr = TAKE_PTR(n);
+
+        return 0;
+}
+
+int config_parse_hwaddrs(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_set_free_free_ Set *s = NULL;
+        const char *p = rvalue;
+        Set **hwaddrs = data;
+        int r;
 
-        if (r || (start[offset + strspn(start + offset, WHITESPACE)] != '\0')) {
-                log_syntax(unit, LOG_ERR, filename, line, 0, "Not a valid MAC address, ignoring assignment: %s", rvalue);
-                free(n);
+        assert(filename);
+        assert(lvalue);
+        assert(rvalue);
+        assert(data);
+
+        if (isempty(rvalue)) {
+                /* Empty assignment resets the list */
+                *hwaddrs = set_free_free(*hwaddrs);
                 return 0;
         }
 
-        free(*hwaddr);
-        *hwaddr = n;
+        s = set_new(&ether_addr_hash_ops);
+        if (!s)
+                return log_oom();
+
+        for (;;) {
+                _cleanup_free_ char *word = NULL;
+                _cleanup_free_ struct ether_addr *n = NULL;
+
+                r = extract_first_word(&p, &word, NULL, 0);
+                if (r == 0)
+                        break;
+                if (r == -ENOMEM)
+                        return log_oom();
+                if (r < 0) {
+                        log_syntax(unit, LOG_WARNING, filename, line, r, "Invalid syntax, ignoring: %s", rvalue);
+                        return 0;
+                }
+
+                n = new(struct ether_addr, 1);
+                if (!n)
+                        return log_oom();
+
+                r = ether_addr_from_string(word, n);
+                if (r < 0) {
+                        log_syntax(unit, LOG_ERR, filename, line, 0, "Not a valid MAC address, ignoring: %s", word);
+                        continue;
+                }
+
+                r = set_put(s, n);
+                if (r < 0)
+                        return log_oom();
+                if (r > 0)
+                        n = NULL; /* avoid cleanup */
+        }
+
+        r = set_ensure_allocated(hwaddrs, &ether_addr_hash_ops);
+        if (r < 0)
+                return log_oom();
+
+        r = set_move(*hwaddrs, s);
+        if (r < 0)
+                return log_oom();
 
         return 0;
 }
@@ -588,14 +656,3 @@ int serialize_dhcp_option(FILE *f, const char *key, const void *data, size_t siz
 
         return 0;
 }
-
-int deserialize_dhcp_option(void **data, size_t *data_len, const char *string) {
-        assert(data);
-        assert(data_len);
-        assert(string);
-
-        if (strlen(string) % 2)
-                return -EINVAL;
-
-        return unhexmem(string, strlen(string), (void **)data, data_len);
-}
index e7fc337e6bf8f3f49a365bad90b8f9a09c2e0c71..5346a82015a94c18db0223325f195dfe1e7e8e25 100644 (file)
 #include "sd-dhcp-lease.h"
 
 #include "condition.h"
+#include "conf-parser.h"
+#include "set.h"
 #include "udev.h"
 
 #define LINK_BRIDGE_PORT_PRIORITY_INVALID 128
 #define LINK_BRIDGE_PORT_PRIORITY_MAX 63
 
-bool net_match_config(const struct ether_addr *match_mac,
+bool net_match_config(Set *match_mac,
                       char * const *match_path,
                       char * const *match_driver,
                       char * const *match_type,
@@ -34,29 +36,13 @@ bool net_match_config(const struct ether_addr *match_mac,
                       const char *dev_type,
                       const char *dev_name);
 
-int config_parse_net_condition(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_hwaddr(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_ifnames(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_ifalias(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_iaid(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_bridge_port_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);
+CONFIG_PARSER_PROTOTYPE(config_parse_net_condition);
+CONFIG_PARSER_PROTOTYPE(config_parse_hwaddr);
+CONFIG_PARSER_PROTOTYPE(config_parse_hwaddrs);
+CONFIG_PARSER_PROTOTYPE(config_parse_ifnames);
+CONFIG_PARSER_PROTOTYPE(config_parse_ifalias);
+CONFIG_PARSER_PROTOTYPE(config_parse_iaid);
+CONFIG_PARSER_PROTOTYPE(config_parse_bridge_port_priority);
 
 int net_get_unique_predictable_data(struct udev_device *device, uint64_t *result);
 const char *net_get_name(struct udev_device *device);
@@ -73,5 +59,5 @@ struct sd_dhcp_route;
 void serialize_dhcp_routes(FILE *f, const char *key, sd_dhcp_route **routes, size_t size);
 int deserialize_dhcp_routes(struct sd_dhcp_route **ret, size_t *ret_size, size_t *ret_allocated, const char *string);
 
+/* It is not necessary to add deserialize_dhcp_option(). Use unhexmem() instead. */
 int serialize_dhcp_option(FILE *f, const char *key, const void *data, size_t size);
-int deserialize_dhcp_option(void **data, size_t *data_len, const char *string);
index 8305815df663a39816f0238f3197a597b66cc69b..5660271330c6137fc5a3b002b470e58ce4ecf34f 100644 (file)
@@ -27,6 +27,7 @@
 #include "random-util.h"
 #include "string-util.h"
 #include "util.h"
+#include "strv.h"
 
 #define MAX_CLIENT_ID_LEN (sizeof(uint32_t) + MAX_DUID_LEN)  /* Arbitrary limit */
 #define MAX_MAC_ADDR_LEN CONST_MAX(INFINIBAND_ALEN, ETH_ALEN)
@@ -83,6 +84,7 @@ struct sd_dhcp_client {
         size_t client_id_len;
         char *hostname;
         char *vendor_class_identifier;
+        char **user_class;
         uint32_t mtu;
         uint32_t xid;
         usec_t start_time;
@@ -440,6 +442,26 @@ int sd_dhcp_client_set_vendor_class_identifier(
         return free_and_strdup(&client->vendor_class_identifier, vci);
 }
 
+int sd_dhcp_client_set_user_class(
+                sd_dhcp_client *client,
+                const char* const* user_class) {
+
+        _cleanup_strv_free_ char **s = NULL;
+        char **p;
+
+        STRV_FOREACH(p, (char **) user_class)
+                if (strlen(*p) > 255)
+                        return -ENAMETOOLONG;
+
+        s = strv_copy((char **) user_class);
+        if (!s)
+                return -ENOMEM;
+
+        client->user_class = TAKE_PTR(s);
+
+        return 0;
+}
+
 int sd_dhcp_client_set_client_port(
                 sd_dhcp_client *client,
                 uint16_t port) {
@@ -763,6 +785,15 @@ static int client_send_discover(sd_dhcp_client *client) {
                         return r;
         }
 
+        if (client->user_class) {
+                r = dhcp_option_append(&discover->dhcp, optlen, &optoffset, 0,
+                                       SD_DHCP_OPTION_USER_CLASS,
+                                       strv_length(client->user_class),
+                                       client->user_class);
+                if (r < 0)
+                        return r;
+        }
+
         r = dhcp_option_append(&discover->dhcp, optlen, &optoffset, 0,
                                SD_DHCP_OPTION_END, 0, NULL);
         if (r < 0)
@@ -1918,6 +1949,7 @@ sd_dhcp_client *sd_dhcp_client_unref(sd_dhcp_client *client) {
         free(client->req_opts);
         free(client->hostname);
         free(client->vendor_class_identifier);
+        client->user_class = strv_free(client->user_class);
         return mfree(client);
 }
 
index c4670503cc004fe3aa82ea004100431706949602..505d02b50dfaa8f472270b22f5094ffd122fc876 100644 (file)
@@ -667,7 +667,7 @@ int dhcp_lease_parse_options(uint8_t code, uint8_t len, const void *option, void
                         return 0;
                 }
 
-                if (!timezone_is_valid(tz)) {
+                if (!timezone_is_valid(tz, LOG_DEBUG)) {
                         log_debug_errno(r, "Timezone is not valid, ignoring: %m");
                         return 0;
                 }
@@ -1193,13 +1193,13 @@ int dhcp_lease_load(sd_dhcp_lease **ret, const char *lease_file) {
         }
 
         if (client_id_hex) {
-                r = deserialize_dhcp_option(&lease->client_id, &lease->client_id_len, client_id_hex);
+                r = unhexmem(client_id_hex, (size_t) -1, &lease->client_id, &lease->client_id_len);
                 if (r < 0)
                         log_debug_errno(r, "Failed to parse client ID %s, ignoring: %m", client_id_hex);
         }
 
         if (vendor_specific_hex) {
-                r = deserialize_dhcp_option(&lease->vendor_specific, &lease->vendor_specific_len, vendor_specific_hex);
+                r = unhexmem(vendor_specific_hex, (size_t) -1, &lease->vendor_specific, &lease->vendor_specific_len);
                 if (r < 0)
                         log_debug_errno(r, "Failed to parse vendor specific data %s, ignoring: %m", vendor_specific_hex);
         }
@@ -1211,7 +1211,7 @@ int dhcp_lease_load(sd_dhcp_lease **ret, const char *lease_file) {
                 if (!options[i])
                         continue;
 
-                r = deserialize_dhcp_option(&data, &len, options[i]);
+                r = unhexmem(options[i], (size_t) -1, &data, &len);
                 if (r < 0) {
                         log_debug_errno(r, "Failed to parse private DHCP option %s, ignoring: %m", options[i]);
                         continue;
index 351b56742386cc0d93d14151b076d6ac54c6132b..d97bb9a0754dd26595a77172f4e0239c523435f0 100644 (file)
@@ -1069,7 +1069,7 @@ int sd_dhcp_server_set_timezone(sd_dhcp_server *server, const char *tz) {
         int r;
 
         assert_return(server, -EINVAL);
-        assert_return(timezone_is_valid(tz), -EINVAL);
+        assert_return(timezone_is_valid(tz, LOG_DEBUG), -EINVAL);
 
         if (streq_ptr(tz, server->timezone))
                 return 0;
index 88c0b1fbd2b8178fd2a2de2cf2014820aaee9d4f..fc77a788f42db86fe150292cc1e12a142d7e0da9 100644 (file)
@@ -248,8 +248,7 @@ int dhcp6_lease_set_domains(sd_dhcp6_lease *lease, uint8_t *optval,
         if (r < 0)
                 return 0;
 
-        strv_free(lease->domains);
-        lease->domains = domains;
+        strv_free_and_replace(lease->domains, domains);
         lease->domains_count = r;
 
         return r;
@@ -308,8 +307,7 @@ int dhcp6_lease_set_ntp(sd_dhcp6_lease *lease, uint8_t *optval, size_t optlen) {
                         if (r < 0)
                                 return 0;
 
-                        lease->ntp_fqdn = strv_free(lease->ntp_fqdn);
-                        lease->ntp_fqdn = servers;
+                        strv_free_and_replace(lease->ntp_fqdn, servers);
                         lease->ntp_fqdn_count = r;
 
                         break;
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 7e55aec35b1aeea7e819a288a630d792688ccf17..ce4cd418442f95072bda6b9c2a5e9e1a4ad2a16d 100644 (file)
@@ -82,15 +82,17 @@ libsystemd_sources = files('''
         sd-utf8/sd-utf8.c
 '''.split()) + id128_sources + sd_daemon_c + sd_event_c + sd_login_c
 
+libsystemd_c_args = ['-fvisibility=default']
+
 libsystemd_static = static_library(
-        'systemd',
+        'systemd_static',
         libsystemd_sources,
         install : false,
         include_directories : includes,
         link_with : libbasic,
         dependencies : [threads,
                         librt],
-        c_args : ['-fvisibility=default'])
+        c_args : libsystemd_c_args)
 
 libsystemd_sym = 'src/libsystemd/libsystemd.sym'
 
index 428e02612c99345f5c9d274a2a0b70f0f07e42a5..e84ea0f6bff71a665988f408e099cdd4b7dfe98e 100644 (file)
@@ -325,7 +325,7 @@ struct sd_bus {
 #define BUS_WQUEUE_MAX (192*1024)
 #define BUS_RQUEUE_MAX (192*1024)
 
-#define BUS_MESSAGE_SIZE_MAX (64*1024*1024)
+#define BUS_MESSAGE_SIZE_MAX (128*1024*1024)
 #define BUS_AUTH_SIZE_MAX (64*1024)
 
 #define BUS_CONTAINER_DEPTH 128
index 61df50e43aa6e078c8e947ec612e078771f93fb0..63e7c01ef13cb383b39fd324fc111cdaef733ac9 100644 (file)
@@ -96,7 +96,7 @@ static void message_reset_containers(sd_bus_message *m) {
         m->root_container.index = 0;
 }
 
-static void message_free(sd_bus_message *m) {
+static sd_bus_message* message_free(sd_bus_message *m) {
         assert(m);
 
         if (m->free_header)
@@ -121,9 +121,11 @@ static void message_free(sd_bus_message *m) {
         free(m->root_container.peeked_signature);
 
         bus_creds_done(&m->creds);
-        free(m);
+        return mfree(m);
 }
 
+DEFINE_TRIVIAL_CLEANUP_FUNC(sd_bus_message*, message_free);
+
 static void *message_extend_fields(sd_bus_message *m, size_t align, size_t sz, bool add_offset) {
         void *op, *np;
         size_t old_size, new_size, start;
@@ -514,7 +516,7 @@ int bus_message_from_malloc(
                 const char *label,
                 sd_bus_message **ret) {
 
-        sd_bus_message *m;
+        _cleanup_(message_freep) sd_bus_message *m = NULL;
         size_t sz;
         int r;
 
@@ -545,18 +547,14 @@ int bus_message_from_malloc(
 
         r = bus_message_parse_fields(m);
         if (r < 0)
-                goto fail;
+                return r;
 
         /* We take possession of the memory and fds now */
         m->free_header = true;
         m->free_fds = true;
 
-        *ret = m;
+        *ret = TAKE_PTR(m);
         return 0;
-
-fail:
-        message_free(m);
-        return r;
 }
 
 _public_ int sd_bus_message_new(
@@ -598,7 +596,7 @@ _public_ int sd_bus_message_new_signal(
                 const char *interface,
                 const char *member) {
 
-        sd_bus_message *t;
+        _cleanup_(sd_bus_message_unrefp) sd_bus_message *t = NULL;
         int r;
 
         assert_return(bus, -ENOTCONN);
@@ -618,20 +616,16 @@ _public_ int sd_bus_message_new_signal(
 
         r = message_append_field_string(t, BUS_MESSAGE_HEADER_PATH, SD_BUS_TYPE_OBJECT_PATH, path, &t->path);
         if (r < 0)
-                goto fail;
+                return r;
         r = message_append_field_string(t, BUS_MESSAGE_HEADER_INTERFACE, SD_BUS_TYPE_STRING, interface, &t->interface);
         if (r < 0)
-                goto fail;
+                return r;
         r = message_append_field_string(t, BUS_MESSAGE_HEADER_MEMBER, SD_BUS_TYPE_STRING, member, &t->member);
         if (r < 0)
-                goto fail;
+                return r;
 
-        *m = t;
+        *m = TAKE_PTR(t);
         return 0;
-
-fail:
-        sd_bus_message_unref(t);
-        return r;
 }
 
 _public_ int sd_bus_message_new_method_call(
@@ -642,7 +636,7 @@ _public_ int sd_bus_message_new_method_call(
                 const char *interface,
                 const char *member) {
 
-        sd_bus_message *t;
+        _cleanup_(message_freep) sd_bus_message *t = NULL;
         int r;
 
         assert_return(bus, -ENOTCONN);
@@ -661,29 +655,25 @@ _public_ int sd_bus_message_new_method_call(
 
         r = message_append_field_string(t, BUS_MESSAGE_HEADER_PATH, SD_BUS_TYPE_OBJECT_PATH, path, &t->path);
         if (r < 0)
-                goto fail;
+                return r;
         r = message_append_field_string(t, BUS_MESSAGE_HEADER_MEMBER, SD_BUS_TYPE_STRING, member, &t->member);
         if (r < 0)
-                goto fail;
+                return r;
 
         if (interface) {
                 r = message_append_field_string(t, BUS_MESSAGE_HEADER_INTERFACE, SD_BUS_TYPE_STRING, interface, &t->interface);
                 if (r < 0)
-                        goto fail;
+                        return r;
         }
 
         if (destination) {
                 r = message_append_field_string(t, BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, destination, &t->destination);
                 if (r < 0)
-                        goto fail;
+                        return r;
         }
 
-        *m = t;
+        *m = TAKE_PTR(t);
         return 0;
-
-fail:
-        message_free(t);
-        return r;
 }
 
 static int message_new_reply(
@@ -691,7 +681,7 @@ static int message_new_reply(
                 uint8_t type,
                 sd_bus_message **m) {
 
-        sd_bus_message *t;
+        _cleanup_(message_freep) sd_bus_message *t = NULL;
         uint64_t cookie;
         int r;
 
@@ -715,23 +705,19 @@ static int message_new_reply(
         t->reply_cookie = cookie;
         r = message_append_reply_cookie(t, t->reply_cookie);
         if (r < 0)
-                goto fail;
+                return r;
 
         if (call->sender) {
                 r = message_append_field_string(t, BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, call->sender, &t->destination);
                 if (r < 0)
-                        goto fail;
+                        return r;
         }
 
         t->dont_send = !!(call->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED);
         t->enforced_reply_signature = call->enforced_reply_signature;
 
-        *m = t;
+        *m = TAKE_PTR(t);
         return 0;
-
-fail:
-        message_free(t);
-        return r;
 }
 
 _public_ int sd_bus_message_new_method_return(
@@ -746,7 +732,7 @@ _public_ int sd_bus_message_new_method_error(
                 sd_bus_message **m,
                 const sd_bus_error *e) {
 
-        sd_bus_message *t;
+        _cleanup_(message_freep) sd_bus_message *t = NULL;
         int r;
 
         assert_return(sd_bus_error_is_set(e), -EINVAL);
@@ -758,22 +744,18 @@ _public_ int sd_bus_message_new_method_error(
 
         r = message_append_field_string(t, BUS_MESSAGE_HEADER_ERROR_NAME, SD_BUS_TYPE_STRING, e->name, &t->error.name);
         if (r < 0)
-                goto fail;
+                return r;
 
         if (e->message) {
                 r = message_append_basic(t, SD_BUS_TYPE_STRING, e->message, (const void**) &t->error.message);
                 if (r < 0)
-                        goto fail;
+                        return r;
         }
 
         t->error._need_free = -1;
 
-        *m = t;
+        *m = TAKE_PTR(t);
         return 0;
-
-fail:
-        message_free(t);
-        return r;
 }
 
 _public_ int sd_bus_message_new_method_errorf(
@@ -853,7 +835,7 @@ int bus_message_new_synthetic_error(
                 const sd_bus_error *e,
                 sd_bus_message **m) {
 
-        sd_bus_message *t;
+        _cleanup_(message_freep) sd_bus_message *t = NULL;
         int r;
 
         assert(bus);
@@ -871,34 +853,30 @@ int bus_message_new_synthetic_error(
 
         r = message_append_reply_cookie(t, t->reply_cookie);
         if (r < 0)
-                goto fail;
+                return r;
 
         if (bus && bus->unique_name) {
                 r = message_append_field_string(t, BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, bus->unique_name, &t->destination);
                 if (r < 0)
-                        goto fail;
+                        return r;
         }
 
         r = message_append_field_string(t, BUS_MESSAGE_HEADER_ERROR_NAME, SD_BUS_TYPE_STRING, e->name, &t->error.name);
         if (r < 0)
-                goto fail;
+                return r;
 
         if (e->message) {
                 r = message_append_basic(t, SD_BUS_TYPE_STRING, e->message, (const void**) &t->error.message);
                 if (r < 0)
-                        goto fail;
+                        return r;
         }
 
         t->error._need_free = -1;
 
         bus_message_set_sender_driver(bus, t);
 
-        *m = t;
+        *m = TAKE_PTR(t);
         return 0;
-
-fail:
-        message_free(t);
-        return r;
 }
 
 _public_ sd_bus_message* sd_bus_message_ref(sd_bus_message *m) {
index 54feddf9e542ee8d66af850ad754288299b582ab..04839bada415d544db18f6b290dc8453f0424007 100644 (file)
@@ -777,7 +777,7 @@ static int bus_socket_inotify_setup(sd_bus *b) {
                         if (IN_SET(errno, ENOENT, ELOOP))
                                 break; /* This component doesn't exist yet, or the path contains a cyclic symlink right now */
 
-                        r = log_debug_errno(errno, "Failed to add inotify watch on %s: %m", isempty(prefix) ? "/" : prefix);
+                        r = log_debug_errno(errno, "Failed to add inotify watch on %s: %m", empty_to_root(prefix));
                         goto fail;
                 } else
                         new_watches[n++] = wd;
index 0c38589c2d4f6510646d051bcd58e6655683f5bc..c1974dabe79c1d2a6ed3d8ad7b531ac4b3de4d23 100644 (file)
@@ -163,7 +163,7 @@ static void bus_reset_queues(sd_bus *b) {
         b->wqueue_allocated = 0;
 }
 
-static void bus_free(sd_bus *b) {
+static sd_bus* bus_free(sd_bus *b) {
         sd_bus_slot *s;
 
         assert(b);
@@ -228,56 +228,47 @@ static void bus_free(sd_bus *b) {
 
         assert_se(pthread_mutex_destroy(&b->memfd_cache_mutex) == 0);
 
-        free(b);
+        return mfree(b);
 }
 
+DEFINE_TRIVIAL_CLEANUP_FUNC(sd_bus*, bus_free);
+
 _public_ int sd_bus_new(sd_bus **ret) {
-        sd_bus *r;
+        _cleanup_free_ sd_bus *b = NULL;
 
         assert_return(ret, -EINVAL);
 
-        r = new0(sd_bus, 1);
-        if (!r)
+        b = new0(sd_bus, 1);
+        if (!b)
                 return -ENOMEM;
 
-        r->n_ref = REFCNT_INIT;
-        r->input_fd = r->output_fd = -1;
-        r->inotify_fd = -1;
-        r->message_version = 1;
-        r->creds_mask |= SD_BUS_CREDS_WELL_KNOWN_NAMES|SD_BUS_CREDS_UNIQUE_NAME;
-        r->accept_fd = true;
-        r->original_pid = getpid_cached();
-        r->n_groups = (size_t) -1;
-
-        assert_se(pthread_mutex_init(&r->memfd_cache_mutex, NULL) == 0);
-
-        /* We guarantee that wqueue always has space for at least one
-         * entry */
-        if (!GREEDY_REALLOC(r->wqueue, r->wqueue_allocated, 1)) {
-                free(r);
+        b->n_ref = REFCNT_INIT;
+        b->input_fd = b->output_fd = -1;
+        b->inotify_fd = -1;
+        b->message_version = 1;
+        b->creds_mask |= SD_BUS_CREDS_WELL_KNOWN_NAMES|SD_BUS_CREDS_UNIQUE_NAME;
+        b->accept_fd = true;
+        b->original_pid = getpid_cached();
+        b->n_groups = (size_t) -1;
+
+        assert_se(pthread_mutex_init(&b->memfd_cache_mutex, NULL) == 0);
+
+        /* We guarantee that wqueue always has space for at least one entry */
+        if (!GREEDY_REALLOC(b->wqueue, b->wqueue_allocated, 1))
                 return -ENOMEM;
-        }
 
-        *ret = r;
+        *ret = TAKE_PTR(b);
         return 0;
 }
 
 _public_ int sd_bus_set_address(sd_bus *bus, const char *address) {
-        char *a;
-
         assert_return(bus, -EINVAL);
         assert_return(bus = bus_resolve(bus), -ENOPKG);
         assert_return(bus->state == BUS_UNSET, -EPERM);
         assert_return(address, -EINVAL);
         assert_return(!bus_pid_changed(bus), -ECHILD);
 
-        a = strdup(address);
-        if (!a)
-                return -ENOMEM;
-
-        free_and_replace(bus->address, a);
-
-        return 0;
+        return free_and_strdup(&bus->address, address);
 }
 
 _public_ int sd_bus_set_fd(sd_bus *bus, int input_fd, int output_fd) {
@@ -294,7 +285,8 @@ _public_ int sd_bus_set_fd(sd_bus *bus, int input_fd, int output_fd) {
 }
 
 _public_ int sd_bus_set_exec(sd_bus *bus, const char *path, char *const argv[]) {
-        char *p, **a;
+        _cleanup_strv_free_ char **a = NULL;
+        int r;
 
         assert_return(bus, -EINVAL);
         assert_return(bus = bus_resolve(bus), -ENOPKG);
@@ -303,22 +295,15 @@ _public_ int sd_bus_set_exec(sd_bus *bus, const char *path, char *const argv[])
         assert_return(!strv_isempty(argv), -EINVAL);
         assert_return(!bus_pid_changed(bus), -ECHILD);
 
-        p = strdup(path);
-        if (!p)
-                return -ENOMEM;
-
         a = strv_copy(argv);
-        if (!a) {
-                free(p);
+        if (!a)
                 return -ENOMEM;
-        }
-
-        free_and_replace(bus->exec_path, p);
 
-        strv_free(bus->exec_argv);
-        bus->exec_argv = a;
+        r = free_and_strdup(&bus->exec_path, path);
+        if (r < 0)
+                return r;
 
-        return 0;
+        return strv_free_and_replace(bus->exec_argv, a);
 }
 
 _public_ int sd_bus_set_bus_client(sd_bus *bus, int b) {
@@ -542,7 +527,6 @@ void bus_set_state(sd_bus *bus, enum bus_state state) {
 
 static int hello_callback(sd_bus_message *reply, void *userdata, sd_bus_error *error) {
         const char *s;
-        char *t;
         sd_bus *bus;
         int r;
 
@@ -562,11 +546,9 @@ static int hello_callback(sd_bus_message *reply, void *userdata, sd_bus_error *e
         if (!service_name_is_valid(s) || s[0] != ':')
                 return -EBADMSG;
 
-        t = strdup(s);
-        if (!t)
-                return -ENOMEM;
-
-        free_and_replace(bus->unique_name, t);
+        r = free_and_strdup(&bus->unique_name, s);
+        if (r < 0)
+                return r;
 
         if (bus->state == BUS_HELLO) {
                 bus_set_state(bus, BUS_RUNNING);
@@ -1208,7 +1190,7 @@ _public_ int sd_bus_start(sd_bus *bus) {
 
 _public_ int sd_bus_open_with_description(sd_bus **ret, const char *description) {
         const char *e;
-        sd_bus *b;
+        _cleanup_(bus_freep) sd_bus *b = NULL;
         int r;
 
         assert_return(ret, -EINVAL);
@@ -1239,7 +1221,7 @@ _public_ int sd_bus_open_with_description(sd_bus **ret, const char *description)
 
         r = sd_bus_set_address(b, e);
         if (r < 0)
-                goto fail;
+                return r;
 
         b->bus_client = true;
 
@@ -1251,14 +1233,10 @@ _public_ int sd_bus_open_with_description(sd_bus **ret, const char *description)
 
         r = sd_bus_start(b);
         if (r < 0)
-                goto fail;
+                return r;
 
-        *ret = b;
+        *ret = TAKE_PTR(b);
         return 0;
-
-fail:
-        bus_free(b);
-        return r;
 }
 
 _public_ int sd_bus_open(sd_bus **ret) {
@@ -1277,7 +1255,7 @@ int bus_set_address_system(sd_bus *b) {
 }
 
 _public_ int sd_bus_open_system_with_description(sd_bus **ret, const char *description) {
-        sd_bus *b;
+        _cleanup_(bus_freep) sd_bus *b = NULL;
         int r;
 
         assert_return(ret, -EINVAL);
@@ -1289,12 +1267,12 @@ _public_ int sd_bus_open_system_with_description(sd_bus **ret, const char *descr
         if (description) {
                 r = sd_bus_set_description(b, description);
                 if (r < 0)
-                        goto fail;
+                        return r;
         }
 
         r = bus_set_address_system(b);
         if (r < 0)
-                goto fail;
+                return r;
 
         b->bus_client = true;
         b->is_system = true;
@@ -1307,14 +1285,10 @@ _public_ int sd_bus_open_system_with_description(sd_bus **ret, const char *descr
 
         r = sd_bus_start(b);
         if (r < 0)
-                goto fail;
+                return r;
 
-        *ret = b;
+        *ret = TAKE_PTR(b);
         return 0;
-
-fail:
-        bus_free(b);
-        return r;
 }
 
 _public_ int sd_bus_open_system(sd_bus **ret) {
@@ -1348,7 +1322,7 @@ int bus_set_address_user(sd_bus *b) {
 }
 
 _public_ int sd_bus_open_user_with_description(sd_bus **ret, const char *description) {
-        sd_bus *b;
+        _cleanup_(bus_freep) sd_bus *b = NULL;
         int r;
 
         assert_return(ret, -EINVAL);
@@ -1360,12 +1334,12 @@ _public_ int sd_bus_open_user_with_description(sd_bus **ret, const char *descrip
         if (description) {
                 r = sd_bus_set_description(b, description);
                 if (r < 0)
-                        goto fail;
+                        return r;
         }
 
         r = bus_set_address_user(b);
         if (r < 0)
-                goto fail;
+                return r;
 
         b->bus_client = true;
         b->is_user = true;
@@ -1377,14 +1351,10 @@ _public_ int sd_bus_open_user_with_description(sd_bus **ret, const char *descrip
 
         r = sd_bus_start(b);
         if (r < 0)
-                goto fail;
+                return r;
 
-        *ret = b;
+        *ret = TAKE_PTR(b);
         return 0;
-
-fail:
-        bus_free(b);
-        return r;
 }
 
 _public_ int sd_bus_open_user(sd_bus **ret) {
@@ -1405,7 +1375,7 @@ int bus_set_address_system_remote(sd_bus *b, const char *host) {
 
                 /* Let's make sure this is not a port of some kind,
                  * and is a valid machine name. */
-                if (!in_charset(m, "0123456789") && machine_name_is_valid(m)) {
+                if (!in_charset(m, DIGITS) && machine_name_is_valid(m)) {
                         char *t;
 
                         /* Cut out the host part */
@@ -1428,41 +1398,35 @@ int bus_set_address_system_remote(sd_bus *b, const char *host) {
         if (!a)
                 return -ENOMEM;
 
-        free_and_replace(b->address, a);
-
-        return 0;
- }
+        return free_and_replace(b->address, a);
+}
 
 _public_ int sd_bus_open_system_remote(sd_bus **ret, const char *host) {
-        sd_bus *bus;
+        _cleanup_(bus_freep) sd_bus *b = NULL;
         int r;
 
         assert_return(host, -EINVAL);
         assert_return(ret, -EINVAL);
 
-        r = sd_bus_new(&bus);
+        r = sd_bus_new(&b);
         if (r < 0)
                 return r;
 
-        r = bus_set_address_system_remote(bus, host);
+        r = bus_set_address_system_remote(b, host);
         if (r < 0)
-                goto fail;
+                return r;
 
-        bus->bus_client = true;
-        bus->trusted = false;
-        bus->is_system = true;
-        bus->is_local = false;
+        b->bus_client = true;
+        b->trusted = false;
+        b->is_system = true;
+        b->is_local = false;
 
-        r = sd_bus_start(bus);
+        r = sd_bus_start(b);
         if (r < 0)
-                goto fail;
+                return r;
 
-        *ret = bus;
+        *ret = TAKE_PTR(b);
         return 0;
-
-fail:
-        bus_free(bus);
-        return r;
 }
 
 int bus_set_address_system_machine(sd_bus *b, const char *machine) {
@@ -1480,46 +1444,39 @@ int bus_set_address_system_machine(sd_bus *b, const char *machine) {
         if (!a)
                 return -ENOMEM;
 
-        free_and_replace(b->address, a);
-
-        return 0;
+        return free_and_replace(b->address, a);
 }
 
 _public_ int sd_bus_open_system_machine(sd_bus **ret, const char *machine) {
-        sd_bus *bus;
+        _cleanup_(bus_freep) sd_bus *b = NULL;
         int r;
 
         assert_return(machine, -EINVAL);
         assert_return(ret, -EINVAL);
         assert_return(machine_name_is_valid(machine), -EINVAL);
 
-        r = sd_bus_new(&bus);
+        r = sd_bus_new(&b);
         if (r < 0)
                 return r;
 
-        r = bus_set_address_system_machine(bus, machine);
+        r = bus_set_address_system_machine(b, machine);
         if (r < 0)
-                goto fail;
+                return r;
 
-        bus->bus_client = true;
-        bus->trusted = false;
-        bus->is_system = true;
-        bus->is_local = false;
+        b->bus_client = true;
+        b->trusted = false;
+        b->is_system = true;
+        b->is_local = false;
 
-        r = sd_bus_start(bus);
+        r = sd_bus_start(b);
         if (r < 0)
-                goto fail;
+                return r;
 
-        *ret = bus;
+        *ret = TAKE_PTR(b);
         return 0;
-
-fail:
-        bus_free(bus);
-        return r;
 }
 
 _public_ void sd_bus_close(sd_bus *bus) {
-
         if (!bus)
                 return;
         if (bus->state == BUS_CLOSED)
@@ -1543,7 +1500,6 @@ _public_ void sd_bus_close(sd_bus *bus) {
 }
 
 _public_ sd_bus* sd_bus_flush_close_unref(sd_bus *bus) {
-
         if (!bus)
                 return NULL;
 
@@ -1566,7 +1522,6 @@ void bus_enter_closing(sd_bus *bus) {
 }
 
 _public_ sd_bus *sd_bus_ref(sd_bus *bus) {
-
         if (!bus)
                 return NULL;
 
@@ -1585,12 +1540,10 @@ _public_ sd_bus *sd_bus_unref(sd_bus *bus) {
         if (i > 0)
                 return NULL;
 
-        bus_free(bus);
-        return NULL;
+        return bus_free(bus);
 }
 
 _public_ int sd_bus_is_open(sd_bus *bus) {
-
         assert_return(bus, -EINVAL);
         assert_return(bus = bus_resolve(bus), -ENOPKG);
         assert_return(!bus_pid_changed(bus), -ECHILD);
index f862dc06e850e6ba23a2d183ba989e4e58595e8f..373d596437f9540b5665ae40ed4b8b62567cd881 100644 (file)
@@ -68,7 +68,8 @@ static void *server(void *p) {
 
                 if (sd_bus_message_is_method_call(m, "org.freedesktop.systemd.test", "Exit")) {
 
-                        assert_se((sd_bus_can_send(bus, 'h') >= 1) == (c->server_negotiate_unix_fds && c->client_negotiate_unix_fds));
+                        assert_se((sd_bus_can_send(bus, 'h') >= 1) ==
+                                  (c->server_negotiate_unix_fds && c->client_negotiate_unix_fds));
 
                         r = sd_bus_message_new_method_return(m, &reply);
                         if (r < 0) {
index 701d17b6143a218566969c25505f4e93f68da3b8..f1f4db78abc33c5566a3c184b5ee1736df995d0b 100644 (file)
@@ -7,7 +7,6 @@
   Copyright 2008-2011 Lennart Poettering
 ***/
 
-
 #include "sd-netlink.h"
 
 #include "in-addr-util.h"
index 4877206a2c398d6763554e7bf10b31e647201e29..fcf4d2ef6db12cd26a8371e60af4ddea1ab777e1 100644 (file)
@@ -168,8 +168,15 @@ static void resolve_query_disconnect(sd_resolve_query *q);
 #define RESOLVE_DONT_DESTROY(resolve) \
         _cleanup_(sd_resolve_unrefp) _unused_ sd_resolve *_dont_destroy_##resolve = sd_resolve_ref(resolve)
 
-static int send_died(int out_fd) {
+static void query_assign_errno(sd_resolve_query *q, int ret, int error, int h_error) {
+        assert(q);
+
+        q->ret = ret;
+        q->_errno = abs(error);
+        q->_h_errno = h_error;
+}
 
+static int send_died(int out_fd) {
         RHeader rh = {
                 .type = RESPONSE_DIED,
                 .length = sizeof(RHeader),
@@ -231,12 +238,12 @@ static int send_addrinfo_reply(
                 ._h_errno = _h_errno,
         };
 
-        struct msghdr mh = {};
-        struct iovec iov[2];
         union {
                 AddrInfoSerialization ais;
                 uint8_t space[BUFSIZE];
         } buffer;
+        struct iovec iov[2];
+        struct msghdr mh;
 
         assert(out_fd >= 0);
 
@@ -259,8 +266,7 @@ static int send_addrinfo_reply(
         iov[0] = (struct iovec) { .iov_base = &resp, .iov_len = sizeof(AddrInfoResponse) };
         iov[1] = (struct iovec) { .iov_base = &buffer, .iov_len = resp.header.length - sizeof(AddrInfoResponse) };
 
-        mh.msg_iov = iov;
-        mh.msg_iovlen = ELEMENTSOF(iov);
+        mh = (struct msghdr) { .msg_iov = iov, .msg_iovlen = ELEMENTSOF(iov) };
 
         if (sendmsg(out_fd, &mh, MSG_NOSIGNAL) < 0)
                 return -errno;
@@ -285,8 +291,8 @@ static int send_nameinfo_reply(
                 ._h_errno = _h_errno,
         };
 
-        struct msghdr mh = {};
         struct iovec iov[3];
+        struct msghdr mh;
         size_t hl, sl;
 
         assert(out_fd >= 0);
@@ -302,8 +308,7 @@ static int send_nameinfo_reply(
         iov[1] = (struct iovec) { .iov_base = (void*) host, .iov_len = hl };
         iov[2] = (struct iovec) { .iov_base = (void*) serv, .iov_len = sl };
 
-        mh.msg_iov = iov;
-        mh.msg_iovlen = ELEMENTSOF(iov);
+        mh = (struct msghdr) { .msg_iov = iov, .msg_iovlen = ELEMENTSOF(iov) };
 
         if (sendmsg(out_fd, &mh, MSG_NOSIGNAL) < 0)
                 return -errno;
@@ -319,32 +324,33 @@ static int handle_request(int out_fd, const Packet *packet, size_t length) {
 
         req = &packet->rheader;
 
-        assert(length >= sizeof(RHeader));
-        assert(length == req->length);
+        assert_return(length >= sizeof(RHeader), -EIO);
+        assert_return(length == req->length, -EIO);
 
         switch (req->type) {
 
         case REQUEST_ADDRINFO: {
                const AddrInfoRequest *ai_req = &packet->addrinfo_request;
-               struct addrinfo hints = {}, *result = NULL;
+               struct addrinfo hints, *result = NULL;
                const char *node, *service;
                int ret;
 
-               assert(length >= sizeof(AddrInfoRequest));
-               assert(length == sizeof(AddrInfoRequest) + ai_req->node_len + ai_req->service_len);
+               assert_return(length >= sizeof(AddrInfoRequest), -EBADMSG);
+               assert_return(length == sizeof(AddrInfoRequest) + ai_req->node_len + ai_req->service_len, -EBADMSG);
 
-               hints.ai_flags = ai_req->ai_flags;
-               hints.ai_family = ai_req->ai_family;
-               hints.ai_socktype = ai_req->ai_socktype;
-               hints.ai_protocol = ai_req->ai_protocol;
+               hints = (struct addrinfo) {
+                       .ai_flags = ai_req->ai_flags,
+                       .ai_family = ai_req->ai_family,
+                       .ai_socktype = ai_req->ai_socktype,
+                       .ai_protocol = ai_req->ai_protocol,
+               };
 
                node = ai_req->node_len ? (const char*) ai_req + sizeof(AddrInfoRequest) : NULL;
                service = ai_req->service_len ? (const char*) ai_req + sizeof(AddrInfoRequest) + ai_req->node_len : NULL;
 
-               ret = getaddrinfo(
-                               node, service,
-                               ai_req->hints_valid ? &hints : NULL,
-                               &result);
+               ret = getaddrinfo(node, service,
+                                 ai_req->hints_valid ? &hints : NULL,
+                                 &result);
 
                /* send_addrinfo_reply() frees result */
                return send_addrinfo_reply(out_fd, req->id, ret, result, errno, h_errno);
@@ -356,21 +362,21 @@ static int handle_request(int out_fd, const Packet *packet, size_t length) {
                union sockaddr_union sa;
                int ret;
 
-               assert(length >= sizeof(NameInfoRequest));
-               assert(length == sizeof(NameInfoRequest) + ni_req->sockaddr_len);
-               assert(sizeof(sa) >= ni_req->sockaddr_len);
+               assert_return(length >= sizeof(NameInfoRequest), -EBADMSG);
+               assert_return(length == sizeof(NameInfoRequest) + ni_req->sockaddr_len, -EBADMSG);
+               assert_return(ni_req->sockaddr_len <= sizeof(sa), -EBADMSG);
 
                memcpy(&sa, (const uint8_t *) ni_req + sizeof(NameInfoRequest), ni_req->sockaddr_len);
 
                ret = getnameinfo(&sa.sa, ni_req->sockaddr_len,
-                               ni_req->gethost ? hostbuf : NULL, ni_req->gethost ? sizeof(hostbuf) : 0,
-                               ni_req->getserv ? servbuf : NULL, ni_req->getserv ? sizeof(servbuf) : 0,
-                               ni_req->flags);
+                                 ni_req->gethost ? hostbuf : NULL, ni_req->gethost ? sizeof(hostbuf) : 0,
+                                 ni_req->getserv ? servbuf : NULL, ni_req->getserv ? sizeof(servbuf) : 0,
+                                 ni_req->flags);
 
                return send_nameinfo_reply(out_fd, req->id, ret,
-                               ret == 0 && ni_req->gethost ? hostbuf : NULL,
-                               ret == 0 && ni_req->getserv ? servbuf : NULL,
-                               errno, h_errno);
+                                          ret == 0 && ni_req->gethost ? hostbuf : NULL,
+                                          ret == 0 && ni_req->getserv ? servbuf : NULL,
+                                          errno, h_errno);
         }
 
         case REQUEST_TERMINATE:
@@ -397,7 +403,7 @@ static void* thread_worker(void *p) {
                 } buf;
                 ssize_t length;
 
-                length = recv(resolve->fds[REQUEST_RECV_FD], &buf, sizeof(buf), 0);
+                length = recv(resolve->fds[REQUEST_RECV_FD], &buf, sizeof buf, 0);
                 if (length < 0) {
                         if (errno == EINTR)
                                 continue;
@@ -407,9 +413,6 @@ static void* thread_worker(void *p) {
                 if (length == 0)
                         break;
 
-                if (resolve->dead)
-                        break;
-
                 if (handle_request(resolve->fds[RESPONSE_SEND_FD], &buf.packet, (size_t) length) < 0)
                         break;
         }
@@ -437,7 +440,6 @@ static int start_threads(sd_resolve *resolve, unsigned extra) {
         n = CLAMP(n, WORKERS_MIN, WORKERS_MAX);
 
         while (resolve->n_valid_workers < n) {
-
                 r = pthread_create(&resolve->workers[resolve->n_valid_workers], NULL, thread_worker, resolve);
                 if (r > 0) {
                         r = -r;
@@ -467,8 +469,8 @@ static bool resolve_pid_changed(sd_resolve *r) {
 }
 
 _public_ int sd_resolve_new(sd_resolve **ret) {
-        sd_resolve *resolve = NULL;
-        int i, r;
+        _cleanup_(sd_resolve_unrefp) sd_resolve *resolve = NULL;
+        int i;
 
         assert_return(ret, -EINVAL);
 
@@ -482,17 +484,11 @@ _public_ int sd_resolve_new(sd_resolve **ret) {
         for (i = 0; i < _FD_MAX; i++)
                 resolve->fds[i] = -1;
 
-        r = socketpair(PF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0, resolve->fds + REQUEST_RECV_FD);
-        if (r < 0) {
-                r = -errno;
-                goto fail;
-        }
+        if (socketpair(PF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0, resolve->fds + REQUEST_RECV_FD) < 0)
+                return -errno;
 
-        r = socketpair(PF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0, resolve->fds + RESPONSE_RECV_FD);
-        if (r < 0) {
-                r = -errno;
-                goto fail;
-        }
+        if (socketpair(PF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0, resolve->fds + RESPONSE_RECV_FD) < 0)
+                return -errno;
 
         for (i = 0; i < _FD_MAX; i++)
                 resolve->fds[i] = fd_move_above_stdio(resolve->fds[i]);
@@ -504,12 +500,8 @@ _public_ int sd_resolve_new(sd_resolve **ret) {
 
         (void) fd_nonblock(resolve->fds[RESPONSE_RECV_FD], true);
 
-        *ret = resolve;
+        *ret = TAKE_PTR(resolve);
         return 0;
-
-fail:
-        sd_resolve_unref(resolve);
-        return r;
 }
 
 _public_ int sd_resolve_default(sd_resolve **ret) {
@@ -578,7 +570,7 @@ static void resolve_free(sd_resolve *resolve) {
 
                 RHeader req = {
                         .type = REQUEST_TERMINATE,
-                        .length = sizeof(req)
+                        .length = sizeof req,
                 };
 
                 /* Send one termination packet for each worker */
@@ -606,7 +598,6 @@ _public_ sd_resolve* sd_resolve_ref(sd_resolve *resolve) {
 }
 
 _public_ sd_resolve* sd_resolve_unref(sd_resolve *resolve) {
-
         if (!resolve)
                 return NULL;
 
@@ -752,11 +743,11 @@ static int handle_response(sd_resolve *resolve, const Packet *packet, size_t len
         int r;
 
         assert(resolve);
+        assert(packet);
 
         resp = &packet->rheader;
-        assert(resp);
-        assert(length >= sizeof(RHeader));
-        assert(length == resp->length);
+        assert_return(length >= sizeof(RHeader), -EIO);
+        assert_return(length == resp->length, -EIO);
 
         if (resp->type == RESPONSE_DIED) {
                 resolve->dead = true;
@@ -778,12 +769,10 @@ static int handle_response(sd_resolve *resolve, const Packet *packet, size_t len
                 size_t l;
                 struct addrinfo *prev = NULL;
 
-                assert(length >= sizeof(AddrInfoResponse));
-                assert(q->type == REQUEST_ADDRINFO);
+                assert_return(length >= sizeof(AddrInfoResponse), -EBADMSG);
+                assert_return(q->type == REQUEST_ADDRINFO, -EBADMSG);
 
-                q->ret = ai_resp->ret;
-                q->_errno = ai_resp->_errno;
-                q->_h_errno = ai_resp->_h_errno;
+                query_assign_errno(q, ai_resp->ret, ai_resp->_errno, ai_resp->_h_errno);
 
                 l = length - sizeof(AddrInfoResponse);
                 p = (const uint8_t*) resp + sizeof(AddrInfoResponse);
@@ -793,9 +782,7 @@ static int handle_response(sd_resolve *resolve, const Packet *packet, size_t len
 
                         r = unserialize_addrinfo(&p, &l, &ai);
                         if (r < 0) {
-                                q->ret = EAI_SYSTEM;
-                                q->_errno = -r;
-                                q->_h_errno = 0;
+                                query_assign_errno(q, EAI_SYSTEM, r, 0);
                                 freeaddrinfo(q->addrinfo);
                                 q->addrinfo = NULL;
                                 break;
@@ -815,39 +802,28 @@ static int handle_response(sd_resolve *resolve, const Packet *packet, size_t len
         case RESPONSE_NAMEINFO: {
                 const NameInfoResponse *ni_resp = &packet->nameinfo_response;
 
-                assert(length >= sizeof(NameInfoResponse));
-                assert(q->type == REQUEST_NAMEINFO);
+                assert_return(length >= sizeof(NameInfoResponse), -EBADMSG);
+                assert_return(q->type == REQUEST_NAMEINFO, -EBADMSG);
 
                 if (ni_resp->hostlen > DNS_HOSTNAME_MAX ||
                     ni_resp->servlen > DNS_HOSTNAME_MAX ||
-                    sizeof(NameInfoResponse) + ni_resp->hostlen + ni_resp->servlen > length + 2) {
-                        q->ret = EAI_SYSTEM;
-                        q->_errno = -EIO;
-                        q->_h_errno = 0;
-
-                } else {
-                        q->ret = ni_resp->ret;
-                        q->_errno = ni_resp->_errno;
-                        q->_h_errno = ni_resp->_h_errno;
+                    sizeof(NameInfoResponse) + ni_resp->hostlen + ni_resp->servlen > length)
+                        query_assign_errno(q, EAI_SYSTEM, EIO, 0);
+                else {
+                        query_assign_errno(q, ni_resp->ret, ni_resp->_errno, ni_resp->_h_errno);
 
                         if (ni_resp->hostlen > 0) {
                                 q->host = strndup((const char*) ni_resp + sizeof(NameInfoResponse),
                                                   ni_resp->hostlen-1);
-                                if (!q->host) {
-                                        q->ret = EAI_MEMORY;
-                                        q->_errno = ENOMEM;
-                                        q->_h_errno = 0;
-                                }
+                                if (!q->host)
+                                        query_assign_errno(q, EAI_MEMORY, ENOMEM, 0);
                         }
 
                         if (ni_resp->servlen > 0) {
                                 q->serv = strndup((const char*) ni_resp + sizeof(NameInfoResponse) + ni_resp->hostlen,
                                                   ni_resp->servlen-1);
-                                if (!q->serv) {
-                                        q->ret = EAI_MEMORY;
-                                        q->_errno = ENOMEM;
-                                        q->_h_errno = 0;
-                                }
+                                if (!q->serv)
+                                        query_assign_errno(q, EAI_MEMORY, ENOMEM, 0);
                         }
                 }
 
@@ -875,7 +851,7 @@ _public_ int sd_resolve_process(sd_resolve *resolve) {
         /* We don't allow recursively invoking sd_resolve_process(). */
         assert_return(!resolve->current, -EBUSY);
 
-        l = recv(resolve->fds[RESPONSE_RECV_FD], &buf, sizeof(buf), 0);
+        l = recv(resolve->fds[RESPONSE_RECV_FD], &buf, sizeof buf, 0);
         if (l < 0) {
                 if (errno == EAGAIN)
                         return 0;
@@ -956,11 +932,12 @@ _public_ int sd_resolve_getaddrinfo(
                 const struct addrinfo *hints,
                 sd_resolve_getaddrinfo_handler_t callback, void *userdata) {
 
-        AddrInfoRequest req = {};
-        struct msghdr mh = {};
+        _cleanup_(sd_resolve_query_unrefp) sd_resolve_query *q = NULL;
+        AddrInfoRequest req;
         struct iovec iov[3];
-        sd_resolve_query *q;
+        struct msghdr mh = {};
         int r;
+        size_t node_len, service_len;
 
         assert_return(resolve, -EINVAL);
         assert_return(node || service, -EINVAL);
@@ -975,20 +952,23 @@ _public_ int sd_resolve_getaddrinfo(
         q->getaddrinfo_handler = callback;
         q->userdata = userdata;
 
-        req.node_len = node ? strlen(node)+1 : 0;
-        req.service_len = service ? strlen(service)+1 : 0;
+        node_len = node ? strlen(node) + 1 : 0;
+        service_len = service ? strlen(service) + 1 : 0;
 
-        req.header.id = q->id;
-        req.header.type = REQUEST_ADDRINFO;
-        req.header.length = sizeof(AddrInfoRequest) + req.node_len + req.service_len;
+        req = (AddrInfoRequest) {
+                .node_len = node_len,
+                .service_len = service_len,
 
-        if (hints) {
-                req.hints_valid = true;
-                req.ai_flags = hints->ai_flags;
-                req.ai_family = hints->ai_family;
-                req.ai_socktype = hints->ai_socktype;
-                req.ai_protocol = hints->ai_protocol;
-        }
+                .header.id = q->id,
+                .header.type = REQUEST_ADDRINFO,
+                .header.length = sizeof(AddrInfoRequest) + node_len + service_len,
+
+                .hints_valid = hints,
+                .ai_flags = hints ? hints->ai_flags : 0,
+                .ai_family = hints ? hints->ai_family : 0,
+                .ai_socktype = hints ? hints->ai_socktype : 0,
+                .ai_protocol = hints ? hints->ai_protocol : 0,
+        };
 
         iov[mh.msg_iovlen++] = (struct iovec) { .iov_base = &req, .iov_len = sizeof(AddrInfoRequest) };
         if (node)
@@ -997,15 +977,14 @@ _public_ int sd_resolve_getaddrinfo(
                 iov[mh.msg_iovlen++] = (struct iovec) { .iov_base = (void*) service, .iov_len = req.service_len };
         mh.msg_iov = iov;
 
-        if (sendmsg(resolve->fds[REQUEST_SEND_FD], &mh, MSG_NOSIGNAL) < 0) {
-                sd_resolve_query_unref(q);
+        if (sendmsg(resolve->fds[REQUEST_SEND_FD], &mh, MSG_NOSIGNAL) < 0)
                 return -errno;
-        }
 
         resolve->n_outstanding++;
 
         if (_q)
                 *_q = q;
+        TAKE_PTR(q);
 
         return 0;
 }
@@ -1030,10 +1009,10 @@ _public_ int sd_resolve_getnameinfo(
                 sd_resolve_getnameinfo_handler_t callback,
                 void *userdata) {
 
-        NameInfoRequest req = {};
-        struct msghdr mh = {};
+        _cleanup_(sd_resolve_query_unrefp) sd_resolve_query *q = NULL;
+        NameInfoRequest req;
         struct iovec iov[2];
-        sd_resolve_query *q;
+        struct msghdr mh;
         int r;
 
         assert_return(resolve, -EINVAL);
@@ -1052,31 +1031,31 @@ _public_ int sd_resolve_getnameinfo(
         q->getnameinfo_handler = callback;
         q->userdata = userdata;
 
-        req.header.id = q->id;
-        req.header.type = REQUEST_NAMEINFO;
-        req.header.length = sizeof(NameInfoRequest) + salen;
+        req = (NameInfoRequest) {
+                .header.id = q->id,
+                .header.type = REQUEST_NAMEINFO,
+                .header.length = sizeof(NameInfoRequest) + salen,
 
-        req.flags = flags;
-        req.sockaddr_len = salen;
-        req.gethost = !!(get & SD_RESOLVE_GET_HOST);
-        req.getserv = !!(get & SD_RESOLVE_GET_SERVICE);
+                .flags = flags,
+                .sockaddr_len = salen,
+                .gethost = !!(get & SD_RESOLVE_GET_HOST),
+                .getserv = !!(get & SD_RESOLVE_GET_SERVICE),
+        };
 
         iov[0] = (struct iovec) { .iov_base = &req, .iov_len = sizeof(NameInfoRequest) };
         iov[1] = (struct iovec) { .iov_base = (void*) sa, .iov_len = salen };
 
-        mh.msg_iov = iov;
-        mh.msg_iovlen = 2;
+        mh = (struct msghdr) { .msg_iov = iov, .msg_iovlen = ELEMENTSOF(iov) };
 
-        if (sendmsg(resolve->fds[REQUEST_SEND_FD], &mh, MSG_NOSIGNAL) < 0) {
-                sd_resolve_query_unref(q);
+        if (sendmsg(resolve->fds[REQUEST_SEND_FD], &mh, MSG_NOSIGNAL) < 0)
                 return -errno;
-        }
-
-        resolve->n_outstanding++;
 
         if (_q)
                 *_q = q;
 
+        resolve->n_outstanding++;
+        TAKE_PTR(q);
+
         return 0;
 }
 
@@ -1087,7 +1066,7 @@ static int getnameinfo_done(sd_resolve_query *q) {
         assert(q->getnameinfo_handler);
 
         errno = q->_errno;
-        h_errno= q->_h_errno;
+        h_errno = q->_h_errno;
 
         return q->getnameinfo_handler(q, q->ret, q->host, q->serv, q->userdata);
 }
index 5ec35e1b4f68a1fb469005e5fe16ade0f12b1df1..7020412ab28b1b467a47326bfecf7be47da2725f 100644 (file)
@@ -103,7 +103,6 @@ int main(int argc, char *argv[]) {
 
                         log_notice_errno(r, "sd_resolve_wait() timed out, but that's OK");
                         exit(EXIT_SUCCESS);
-                        break;
                 }
                 if (r < 0) {
                         log_error_errno(r, "sd_resolve_wait(): %m");
index d5a8f390bc81185f21b4d6976173a08c533cd447..1b787ccec94fe20f17fc6c3639e20cf07b0f7fb4 100644 (file)
@@ -187,7 +187,6 @@ struct udev_list_entry *udev_hwdb_get_properties_list_entry(struct udev_hwdb *hw
  */
 int udev_util_encode_string(const char *str, char *str_enc, size_t len);
 
-
 #ifdef __cplusplus
 } /* extern "C" */
 #endif
index 5e38061f5180470cecc16f8e98668ac47433ebc9..1aca62765879c6c5dcc16a0a871663fa666c1f96 100644 (file)
@@ -250,8 +250,7 @@ int locale_write_data(Context *c, char ***settings) {
                 if (!u)
                         return -ENOMEM;
 
-                strv_free(l);
-                l = u;
+                strv_free_and_replace(l, u);
         }
 
         if (strv_isempty(l)) {
@@ -291,8 +290,7 @@ int vconsole_write_data(Context *c) {
                 if (!u)
                         return -ENOMEM;
 
-                strv_free(l);
-                l = u;
+                strv_free_and_replace(l, u);
         }
 
         if (isempty(c->vc_keymap_toggle))
@@ -309,8 +307,7 @@ int vconsole_write_data(Context *c) {
                 if (!u)
                         return -ENOMEM;
 
-                strv_free(l);
-                l = u;
+                strv_free_and_replace(l, u);
         }
 
         if (strv_isempty(l)) {
@@ -533,9 +530,10 @@ int find_converted_keymap(const char *x11_layout, const char *x11_variant, char
         return 0;
 }
 
-int find_legacy_keymap(Context *c, char **new_keymap) {
+int find_legacy_keymap(Context *c, char **ret) {
         const char *map;
         _cleanup_fclose_ FILE *f = NULL;
+        _cleanup_free_ char *new_keymap = NULL;
         unsigned n = 0;
         unsigned best_matching = 0;
         int r;
@@ -600,7 +598,7 @@ int find_legacy_keymap(Context *c, char **new_keymap) {
                         if (matching > best_matching) {
                                 best_matching = matching;
 
-                                r = free_and_strdup(new_keymap, a[0]);
+                                r = free_and_strdup(&new_keymap, a[0]);
                                 if (r < 0)
                                         return r;
                         }
@@ -620,13 +618,12 @@ int find_legacy_keymap(Context *c, char **new_keymap) {
                 r = find_converted_keymap(l, v, &converted);
                 if (r < 0)
                         return r;
-                if (r > 0) {
-                        free(*new_keymap);
-                        *new_keymap = converted;
-                }
+                if (r > 0)
+                        free_and_replace(new_keymap, converted);
         }
 
-        return (bool) *new_keymap;
+        *ret = TAKE_PTR(new_keymap);
+        return (bool) *ret;
 }
 
 int find_language_fallback(const char *lang, char **language) {
index f7068a44b6bd8dbcc5b8b4d1dff212cbcca89160..473b28de4db3e9094b59c726610f27f1ade5d7ea 100644 (file)
@@ -127,7 +127,6 @@ static void print_status_info(StatusInfo *i) {
 static int show_status(int argc, char **argv, void *userdata) {
         _cleanup_(status_info_clear) StatusInfo info = {};
         static const struct bus_properties_map map[]  = {
-                { "VConsoleKeymap",       "s",  NULL, offsetof(StatusInfo, vconsole_keymap) },
                 { "VConsoleKeymap",       "s",  NULL, offsetof(StatusInfo, vconsole_keymap) },
                 { "VConsoleKeymapToggle", "s",  NULL, offsetof(StatusInfo, vconsole_keymap_toggle) },
                 { "X11Layout",            "s",  NULL, offsetof(StatusInfo, x11_layout) },
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 f73d2f0a7593616174efc062f974495ea154818a..8cea2829884e54a03f58709b79c493d1c6d6c960 100644 (file)
@@ -29,6 +29,7 @@
 #include "sigbus.h"
 #include "signal-util.h"
 #include "spawn-polkit-agent.h"
+#include "string-table.h"
 #include "strv.h"
 #include "sysfs-show.h"
 #include "terminal-util.h"
@@ -1441,6 +1442,11 @@ static int parse_argv(int argc, char *argv[]) {
                         break;
 
                 case 'o':
+                        if (streq(optarg, "help")) {
+                                DUMP_STRING_TABLE(output_mode, OutputMode, _OUTPUT_MODE_MAX);
+                                return 0;
+                        }
+
                         arg_output = output_mode_from_string(optarg);
                         if (arg_output < 0) {
                                 log_error("Unknown output '%s'.", optarg);
@@ -1465,6 +1471,11 @@ static int parse_argv(int argc, char *argv[]) {
                         break;
 
                 case 's':
+                        if (streq(optarg, "help")) {
+                                DUMP_STRING_TABLE(signal, int, _NSIG);
+                                return 0;
+                        }
+
                         arg_signal = signal_from_string(optarg);
                         if (arg_signal < 0) {
                                 log_error("Failed to parse signal string %s.", optarg);
index 70439d767cd81471f7d5a5946d753044e25a0d24..89c2dfddb4a6c3fc4b56d0edaa5e57b1bfc343ee 100644 (file)
@@ -7,6 +7,8 @@
   Copyright 2012 Lennart Poettering
 ***/
 
+#include "conf-parser.h"
+
 typedef enum HandleAction {
         HANDLE_IGNORE,
         HANDLE_POWEROFF,
@@ -36,4 +38,5 @@ const char* handle_action_to_string(HandleAction h) _const_;
 HandleAction handle_action_from_string(const char *s) _pure_;
 
 const char* manager_target_for_action(HandleAction handle);
-int config_parse_handle_action(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);
+
+CONFIG_PARSER_PROTOTYPE(config_parse_handle_action);
index ee4dfff9f11d481a9cf7b473ca423708d737bdd6..7d7db0d8234c3376e65aca62a4f5a2cef9c83516 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;
@@ -2224,7 +2159,7 @@ static int method_cancel_scheduled_shutdown(sd_bus_message *message, void *userd
         cancelled = m->scheduled_shutdown_type != NULL;
         reset_scheduled_shutdown(m);
 
-        if (cancelled) {
+        if (cancelled && m->enable_wall_messages) {
                 _cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL;
                 const char *tty = NULL;
                 uid_t uid = 0;
@@ -2552,7 +2487,7 @@ static int method_set_wall_message(
         int r;
         Manager *m = userdata;
         char *wall_message;
-        int enable_wall_messages;
+        unsigned enable_wall_messages;
 
         assert(message);
         assert(m);
@@ -2729,11 +2664,11 @@ const sd_bus_vtable manager_vtable[] = {
         SD_BUS_PROPERTY("ScheduledShutdown", "(st)", property_get_scheduled_shutdown, 0, 0),
         SD_BUS_PROPERTY("Docked", "b", property_get_docked, 0, 0),
         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("RuntimeDirectorySize", "t", NULL, 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 32626118eb0295a6f923c108050021f34d083663..712260a5a1207cd93d38e6e2a277d26a0ce456cd 100644 (file)
@@ -9,7 +9,6 @@
 
 typedef struct Inhibitor Inhibitor;
 
-
 typedef enum InhibitWhat {
         INHIBIT_SHUTDOWN = 1,
         INHIBIT_SLEEP = 2,
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 f513555142a3f78420cc23ebc0f6deb77049f82c..8d3af6948c797cd67f8da052c10710ab22d4bb63 100644 (file)
@@ -707,7 +707,7 @@ int config_parse_tmpfs_size(
                 void *data,
                 void *userdata) {
 
-        size_t *sz = data;
+        uint64_t *sz = data;
         int r;
 
         assert(filename);
index 18a80b3fdfdf1d86bd284ae54c9521e5ba795bdd..25b52ef792c98fa6ff36401a3662a4e939f033da 100644 (file)
@@ -9,6 +9,7 @@
 
 typedef struct User User;
 
+#include "conf-parser.h"
 #include "list.h"
 #include "logind.h"
 
@@ -80,4 +81,4 @@ UserState user_state_from_string(const char *s) _pure_;
 int bus_user_method_terminate(sd_bus_message *message, void *userdata, sd_bus_error *error);
 int bus_user_method_kill(sd_bus_message *message, void *userdata, sd_bus_error *error);
 
-int config_parse_compat_user_tasks_max(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);
+CONFIG_PARSER_PROTOTYPE(config_parse_compat_user_tasks_max);
index 385c9773995de9dc9a35815c50f1527078882c57..96f48cbd17f037ffb7dc6d76f198dd9227639704 100644 (file)
@@ -389,14 +389,18 @@ static int parse_fdname(const char *fdname, char **session_id, dev_t *dev) {
 
         if (!streq(parts[0], "session"))
                 return -EINVAL;
+
         id = strdup(parts[1]);
         if (!id)
                 return -ENOMEM;
 
         if (!streq(parts[2], "device"))
                 return -EINVAL;
-        r = safe_atou(parts[3], &major) ||
-            safe_atou(parts[4], &minor);
+
+        r = safe_atou(parts[3], &major);
+        if (r < 0)
+                return r;
+        r = safe_atou(parts[4], &minor);
         if (r < 0)
                 return r;
 
index 498a3713615b7d167257da738b8d248cc7c88426..4a80a0977e717b34da2cb70f783596974590323b 100644 (file)
@@ -13,6 +13,7 @@
 #include "sd-bus.h"
 #include "sd-event.h"
 
+#include "conf-parser.h"
 #include "hashmap.h"
 #include "list.h"
 #include "set.h"
@@ -120,7 +121,7 @@ struct Manager {
         usec_t holdoff_timeout_usec;
         sd_event_source *lid_switch_ignore_event_source;
 
-        size_t runtime_dir_size;
+        uint64_t runtime_dir_size;
         uint64_t user_tasks_max;
         uint64_t sessions_max;
         uint64_t inhibitors_max;
@@ -179,8 +180,8 @@ const struct ConfigPerfItem* logind_gperf_lookup(const char *key, GPERF_LEN_TYPE
 
 int manager_set_lid_switch_ignore(Manager *m, usec_t until);
 
-int config_parse_n_autovts(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_tmpfs_size(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);
+CONFIG_PARSER_PROTOTYPE(config_parse_n_autovts);
+CONFIG_PARSER_PROTOTYPE(config_parse_tmpfs_size);
 
 int manager_get_session_from_creds(Manager *m, sd_bus_message *message, const char *name, sd_bus_error *error, Session **ret);
 int manager_get_user_from_creds(Manager *m, sd_bus_message *message, uid_t uid, sd_bus_error *error, User **ret);
index 1e2cf49c431d131e7cc8d14360cd7d0d0ea882d4..273fbed374a8e36dcbecc8552c78e954617e8a30 100644 (file)
@@ -98,7 +98,7 @@ if conf.get('ENABLE_LOGIND') == 1
                 '73-seat-late.rules',
                 input : '73-seat-late.rules.m4',
                 output: '73-seat-late.rules',
-                command : [m4, '-P'] + m4_defines + ['@INPUT@'],
+                command : [meson_apply_m4, config_h, '@INPUT@'],
                 capture : true,
                 install : true,
                 install_dir : udevrulesdir)
@@ -107,7 +107,7 @@ if conf.get('ENABLE_LOGIND') == 1
                 'systemd-user',
                 input : 'systemd-user.m4',
                 output: 'systemd-user',
-                command : [m4, '-P'] + m4_defines + ['@INPUT@'],
+                command : [meson_apply_m4, config_h, '@INPUT@'],
                 capture : true,
                 install : pamconfdir != 'no',
                 install_dir : pamconfdir)
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 c16f54c283285e320468d7c8da9707e998524ce6..eb68eb192b65237ccf11eca40c992adbe435df97 100644 (file)
@@ -46,6 +46,7 @@
 #include "signal-util.h"
 #include "spawn-polkit-agent.h"
 #include "stdio-util.h"
+#include "string-table.h"
 #include "strv.h"
 #include "terminal-util.h"
 #include "unit-name.h"
@@ -335,10 +336,10 @@ static int list_machines(int argc, char *argv[], void *userdata) {
                 r = table_add_many(table,
                                    TABLE_STRING, name,
                                    TABLE_STRING, class,
-                                   TABLE_STRING, strdash_if_empty(service),
-                                   TABLE_STRING, strdash_if_empty(os),
-                                   TABLE_STRING, strdash_if_empty(version_id),
-                                   TABLE_STRING, strdash_if_empty(addresses));
+                                   TABLE_STRING, empty_to_dash(service),
+                                   TABLE_STRING, empty_to_dash(os),
+                                   TABLE_STRING, empty_to_dash(version_id),
+                                   TABLE_STRING, empty_to_dash(addresses));
                 if (r < 0)
                         return log_error_errno(r, "Failed to add table row: %m");
         }
@@ -2859,6 +2860,11 @@ static int parse_argv(int argc, char *argv[]) {
                         break;
 
                 case 'o':
+                        if (streq(optarg, "help")) {
+                                DUMP_STRING_TABLE(output_mode, OutputMode, _OUTPUT_MODE_MAX);
+                                return 0;
+                        }
+
                         arg_output = output_mode_from_string(optarg);
                         if (arg_output < 0) {
                                 log_error("Unknown output '%s'.", optarg);
@@ -2879,6 +2885,11 @@ static int parse_argv(int argc, char *argv[]) {
                         break;
 
                 case 's':
+                        if (streq(optarg, "help")) {
+                                DUMP_STRING_TABLE(signal, int, _NSIG);
+                                return 0;
+                        }
+
                         arg_signal = signal_from_string(optarg);
                         if (arg_signal < 0) {
                                 log_error("Failed to parse signal string %s.", optarg);
@@ -2913,6 +2924,11 @@ static int parse_argv(int argc, char *argv[]) {
                         break;
 
                 case ARG_VERIFY:
+                        if (streq(optarg, "help")) {
+                                DUMP_STRING_TABLE(import_verify, ImportVerify, _IMPORT_VERIFY_MAX);
+                                return 0;
+                        }
+
                         arg_verify = import_verify_from_string(optarg);
                         if (arg_verify < 0) {
                                 log_error("Failed to parse --verify= setting: %s", optarg);
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 85c472100bb79decf554ee8b2c9fc257251db9e1..b1d32d10e9504bcab4eb487f80895c65fe7d5092 100644 (file)
@@ -12,7 +12,6 @@
 #include "missing.h"
 #include "netdev/netdev.h"
 
-
 typedef enum IPVlanMode {
         NETDEV_IPVLAN_MODE_L2 = IPVLAN_MODE_L2,
         NETDEV_IPVLAN_MODE_L3 = IPVLAN_MODE_L3,
index f4a805a87718bf9e73476d08dd53ff30eebff901..31c890923bbe9672af06db6bca12787de2c0e6a3 100644 (file)
@@ -10,6 +10,7 @@
 #include <inttypes.h>
 #include <stdbool.h>
 
+#include "conf-parser.h"
 #include "in-addr-util.h"
 
 typedef struct AddressLabel AddressLabel;
@@ -41,5 +42,5 @@ DEFINE_TRIVIAL_CLEANUP_FUNC(AddressLabel*, address_label_free);
 
 int address_label_configure(AddressLabel *address, Link *link, sd_netlink_message_handler_t callback, bool update);
 
-int config_parse_address_label(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_address_label_prefix(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);
+CONFIG_PARSER_PROTOTYPE(config_parse_address_label);
+CONFIG_PARSER_PROTOTYPE(config_parse_address_label_prefix);
index 23ff94177080ef42490260cbf206e012a1d243c3..de26dbad71dc3d35b8127c5e7ea40c1942bd08d2 100644 (file)
@@ -10,6 +10,7 @@
 #include <inttypes.h>
 #include <stdbool.h>
 
+#include "conf-parser.h"
 #include "in-addr-util.h"
 
 typedef struct Address Address;
@@ -66,9 +67,9 @@ bool address_is_ready(const Address *a);
 
 DEFINE_TRIVIAL_CLEANUP_FUNC(Address*, address_free);
 
-int config_parse_address(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_broadcast(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_label(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_lifetime(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_address_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);
-int config_parse_address_scope(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);
+CONFIG_PARSER_PROTOTYPE(config_parse_address);
+CONFIG_PARSER_PROTOTYPE(config_parse_broadcast);
+CONFIG_PARSER_PROTOTYPE(config_parse_label);
+CONFIG_PARSER_PROTOTYPE(config_parse_lifetime);
+CONFIG_PARSER_PROTOTYPE(config_parse_address_flags);
+CONFIG_PARSER_PROTOTYPE(config_parse_address_scope);
index ecfbe95e5f28f890a43c77a8fca8bd8eb130e835..4bc7b8985ad756f571ef6de56c84da8ad2109cda 100644 (file)
@@ -9,10 +9,12 @@
 
 #include <stdint.h>
 
+#include "conf-parser.h"
+
 typedef struct Link Link;
 
 int br_vlan_configure(Link *link, uint16_t pvid, uint32_t *br_vid_bitmap, uint32_t *br_untagged_bitmap);
 
-int config_parse_brvlan_pvid(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_brvlan_vlan(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_brvlan_untagged(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);
+CONFIG_PARSER_PROTOTYPE(config_parse_brvlan_pvid);
+CONFIG_PARSER_PROTOTYPE(config_parse_brvlan_vlan);
+CONFIG_PARSER_PROTOTYPE(config_parse_brvlan_untagged);
index 9b481c294e676c3183bf30269dd908f2d2187f89..dfe463ecfbdf2bf7cd0a9d499313dd93154ac037 100644 (file)
@@ -7,31 +7,13 @@
   Copyright 2014 Vinay Kulkarni <kulkarniv@vmware.com>
 ***/
 
+#include "conf-parser.h"
+
 typedef struct Manager Manager;
 
 int manager_parse_config_file(Manager *m);
 
 const struct ConfigPerfItem* networkd_gperf_lookup(const char *key, GPERF_LEN_TYPE length);
 
-int config_parse_duid_type(
-                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_duid_rawdata(
-                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);
+CONFIG_PARSER_PROTOTYPE(config_parse_duid_type);
+CONFIG_PARSER_PROTOTYPE(config_parse_duid_rawdata);
index a1d300166bc56143a58a4cc0a7007993e1a73232..d2e79cdda609d3add41fe698df0641835dca57f2 100644 (file)
@@ -748,6 +748,12 @@ int dhcp4_configure(Link *link) {
                         return r;
         }
 
+        if (link->network->dhcp_user_class) {
+                r = sd_dhcp_client_set_user_class(link->dhcp_client, (const char **) link->network->dhcp_user_class);
+                if (r < 0)
+                        return r;
+        }
+
         if (link->network->dhcp_client_port) {
                 r = sd_dhcp_client_set_client_port(link->dhcp_client, link->network->dhcp_client_port);
                 if (r < 0)
index a2ccc6e494304a53f781a52dc151143fe062f703..e9db977036da331954bcb64e20cb1a67d3bfab16 100644 (file)
@@ -189,11 +189,13 @@ static int dhcp6_pd_prefix_distribute(Link *dhcp6_link, Iterator *i,
                 if (r < 0)
                         return r;
 
+                route->family = AF_INET6;
+
                 while (n < n_prefixes) {
                         route_update(route, &prefix, pd_prefix_len, NULL, NULL,
                                      0, 0, RTN_UNREACHABLE);
 
-                        r = route_configure(route, link, NULL);
+                        r = route_configure(route, dhcp6_link, NULL);
                         if (r < 0) {
                                 route_free(route);
                                 return r;
index 04bf69773ac299279ca143f2e9674ca5b21830e6..e3ab53ab9f9b211ba549ab333be3238bff25e2e6 100644 (file)
@@ -7,6 +7,7 @@
   Copyright (C) 2014 Intel Corporation. All rights reserved.
 ***/
 
+#include "conf-parser.h"
 #include "list.h"
 #include "macro.h"
 
@@ -30,5 +31,5 @@ int fdb_entry_configure(Link *link, FdbEntry *fdb_entry);
 
 DEFINE_TRIVIAL_CLEANUP_FUNC(FdbEntry*, fdb_entry_free);
 
-int config_parse_fdb_hwaddr(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_fdb_vlan_id(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);
+CONFIG_PARSER_PROTOTYPE(config_parse_fdb_hwaddr);
+CONFIG_PARSER_PROTOTYPE(config_parse_fdb_vlan_id);
index 8e70df4372f1e27fda3dcd1979558d0dbc8ca23b..b50db8f9fe959a17df4a3375ea4ceff90360262b 100644 (file)
@@ -7,6 +7,7 @@
   Copyright 2017 Florian Klink <flokli@flokli.de>
 ***/
 
+#include "conf-parser.h"
 #include "list.h"
 #include "macro.h"
 
@@ -21,7 +22,6 @@ struct IPv6ProxyNDPAddress {
     LIST_FIELDS(IPv6ProxyNDPAddress, ipv6_proxy_ndp_addresses);
 };
 
-
 int ipv6_proxy_ndp_address_new_static(Network *network, IPv6ProxyNDPAddress ** ipv6_proxy_ndp_address);
 void ipv6_proxy_ndp_address_free(IPv6ProxyNDPAddress *ipv6_proxy_ndp_address);
 int ipv6_proxy_ndp_address_configure(Link *link, IPv6ProxyNDPAddress *ipv6_proxy_ndp_address);
@@ -29,4 +29,4 @@ int ipv6_proxy_ndp_addresses_configure(Link *link);
 
 DEFINE_TRIVIAL_CLEANUP_FUNC(IPv6ProxyNDPAddress*, ipv6_proxy_ndp_address_free);
 
-int config_parse_ipv6_proxy_ndp_address(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);
+CONFIG_PARSER_PROTOTYPE(config_parse_ipv6_proxy_ndp_address);
index 34c496f5521c7e9d83384b9b5407570705b2a8f7..f02b13e28be01fec1419716cfc86cb893a5161a7 100644 (file)
@@ -155,7 +155,7 @@ int manager_connect_bus(Manager *m) {
         if (r < 0)
                 return log_error_errno(r, "Failed to add network enumerator: %m");
 
-        r = sd_bus_request_name_async(m->bus, NULL, "org.freedesktop.network1", 0, NULL, NULL);
+        r = bus_request_name_async_may_reload_dbus(m->bus, NULL, "org.freedesktop.network1", 0, NULL);
         if (r < 0)
                 return log_error_errno(r, "Failed to request name: %m");
 
index 22160ec10b340c1f4bc447eff20782609bb0687f..159537b19ae38a87a72896ed5c3d85360f764f2d 100644 (file)
@@ -6,6 +6,7 @@
 ***/
 
 #include "alloc-util.h"
+#include "ether-addr-util.h"
 #include "networkd-manager.h"
 #include "string-util.h"
 #include "strv.h"
@@ -19,23 +20,24 @@ static int property_get_ether_addrs(
                 void *userdata,
                 sd_bus_error *error) {
 
-        Network *n = userdata;
-        const char *ether = NULL;
+        char buf[ETHER_ADDR_TO_STRING_MAX];
+        const struct ether_addr *p;
+        Iterator i;
+        Set *s;
         int r;
 
         assert(bus);
         assert(reply);
-        assert(n);
+        assert(userdata);
 
-        if (n->match_mac)
-                ether = ether_ntoa(n->match_mac);
+        s = *(Set **) userdata;
 
         r = sd_bus_message_open_container(reply, 'a', "s");
         if (r < 0)
                 return r;
 
-        if (ether) {
-                r = sd_bus_message_append(reply, "s", strempty(ether));
+        SET_FOREACH(p, s, i) {
+                r = sd_bus_message_append(reply, "s", ether_addr_to_string(p, buf));
                 if (r < 0)
                         return r;
         }
@@ -48,7 +50,7 @@ const sd_bus_vtable network_vtable[] = {
 
         SD_BUS_PROPERTY("Description", "s", NULL, offsetof(Network, description), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("SourcePath", "s", NULL, offsetof(Network, filename), SD_BUS_VTABLE_PROPERTY_CONST),
-        SD_BUS_PROPERTY("MatchMAC", "as", property_get_ether_addrs, 0, SD_BUS_VTABLE_PROPERTY_CONST),
+        SD_BUS_PROPERTY("MatchMAC", "as", property_get_ether_addrs, offsetof(Network, match_mac), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("MatchPath", "as", NULL, offsetof(Network, match_path), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("MatchDriver", "as", NULL, offsetof(Network, match_driver), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("MatchType", "as", NULL, offsetof(Network, match_type), SD_BUS_VTABLE_PROPERTY_CONST),
index 1a0da586515b8eadce5751a666a15f4a2abfc522..23f57ca2f0051d6e152aa2dc72c2c61ff2801ec9 100644 (file)
@@ -4,9 +4,9 @@ _Pragma("GCC diagnostic ignored \"-Wimplicit-fallthrough\"")
 #endif
 #include <stddef.h>
 #include "conf-parser.h"
+#include "network-internal.h"
 #include "networkd-conf.h"
 #include "networkd-network.h"
-#include "network-internal.h"
 #include "vlan-util.h"
 %}
 struct ConfigPerfItem;
@@ -20,7 +20,7 @@ struct ConfigPerfItem;
 %struct-type
 %includes
 %%
-Match.MACAddress,                       config_parse_hwaddr                           0,                             offsetof(Network, match_mac)
+Match.MACAddress,                       config_parse_hwaddrs,                           0,                             offsetof(Network, match_mac)
 Match.Path,                             config_parse_strv,                              0,                             offsetof(Network, match_path)
 Match.Driver,                           config_parse_strv,                              0,                             offsetof(Network, match_driver)
 Match.Type,                             config_parse_strv,                              0,                             offsetof(Network, match_type)
@@ -105,6 +105,7 @@ Route.Metric,                           config_parse_route_priority,
 Route.Scope,                            config_parse_route_scope,                       0,                             0
 Route.PreferredSource,                  config_parse_preferred_src,                     0,                             0
 Route.Table,                            config_parse_route_table,                       0,                             0
+Route.MTUBytes,                         config_parse_route_mtu,                         AF_UNSPEC,                     0
 Route.GatewayOnlink,                    config_parse_gateway_onlink,                    0,                             0
 Route.IPv6Preference,                   config_parse_ipv6_route_preference,             0,                             0
 Route.Protocol,                         config_parse_route_protocol,                    0,                             0
@@ -125,6 +126,7 @@ DHCP.Hostname,                          config_parse_hostname,
 DHCP.RequestBroadcast,                  config_parse_bool,                              0,                             offsetof(Network, dhcp_broadcast)
 DHCP.CriticalConnection,                config_parse_bool,                              0,                             offsetof(Network, dhcp_critical)
 DHCP.VendorClassIdentifier,             config_parse_string,                            0,                             offsetof(Network, dhcp_vendor_class_identifier)
+DHCP.UserClass,                         config_parse_dhcp_user_class,                   0,                             offsetof(Network, dhcp_user_class)
 DHCP.DUIDType,                          config_parse_duid_type,                         0,                             offsetof(Network, duid.type)
 DHCP.DUIDRawData,                       config_parse_duid_rawdata,                      0,                             offsetof(Network, duid)
 DHCP.RouteMetric,                       config_parse_unsigned,                          0,                             offsetof(Network, dhcp_route_metric)
index 2592377a6f748fd4d0198a8a462ff76edc4d59a6..2b03fc254ba7a076f68e95ce0bec6f9060038b9f 100644 (file)
@@ -353,7 +353,7 @@ void network_free(Network *network) {
 
         free(network->filename);
 
-        free(network->match_mac);
+        set_free_free(network->match_mac);
         strv_free(network->match_path);
         strv_free(network->match_driver);
         strv_free(network->match_type);
@@ -361,6 +361,7 @@ void network_free(Network *network) {
 
         free(network->description);
         free(network->dhcp_vendor_class_identifier);
+        strv_free(network->dhcp_user_class);
         free(network->dhcp_hostname);
 
         free(network->mac);
@@ -1011,7 +1012,7 @@ int config_parse_timezone(
         if (r < 0)
                 return r;
 
-        if (!timezone_is_valid(tz)) {
+        if (!timezone_is_valid(tz, LOG_ERR)) {
                 log_syntax(unit, LOG_ERR, filename, line, 0, "Timezone is not valid, ignoring assignment: %s", rvalue);
                 free(tz);
                 return 0;
@@ -1387,6 +1388,58 @@ int config_parse_ntp(
         return 0;
 }
 
+int config_parse_dhcp_user_class(
+                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 ***l = data;
+        int r;
+
+        assert(l);
+        assert(lvalue);
+        assert(rvalue);
+
+        if (isempty(rvalue)) {
+                *l = strv_free(*l);
+                return 0;
+        }
+
+        for (;;) {
+                _cleanup_free_ char *w = NULL;
+
+                r = extract_first_word(&rvalue, &w, NULL, 0);
+                if (r == -ENOMEM)
+                        return log_oom();
+                if (r < 0) {
+                        log_syntax(unit, LOG_ERR, filename, line, r, "Failed to split user classes option, ignoring: %s", rvalue);
+                        break;
+                }
+                if (r == 0)
+                        break;
+
+                if (strlen(w) > 255) {
+                        log_syntax(unit, LOG_ERR, filename, line, r, "%s length is not in the range 1-255, ignoring.", w);
+                        continue;
+                }
+
+                r = strv_push(l, w);
+                if (r < 0)
+                        return log_oom();
+
+                w = NULL;
+        }
+
+        return 0;
+}
+
 int config_parse_dhcp_route_table(const char *unit,
                                   const char *filename,
                                   unsigned line,
index 060c526b9ee8dde7666ff2a51fae490891667d3e..c4c6b28ab0d96e4849a9cd9d9a635faaf53eea18 100644 (file)
 #include "udev.h"
 
 #include "condition.h"
+#include "conf-parser.h"
 #include "dhcp-identifier.h"
 #include "hashmap.h"
-#include "resolve-util.h"
-
-#include "networkd-address.h"
+#include "netdev/netdev.h"
 #include "networkd-address-label.h"
+#include "networkd-address.h"
 #include "networkd-brvlan.h"
 #include "networkd-fdb.h"
-#include "networkd-lldp-tx.h"
 #include "networkd-ipv6-proxy-ndp.h"
+#include "networkd-lldp-tx.h"
 #include "networkd-radv.h"
 #include "networkd-route.h"
 #include "networkd-routing-policy-rule.h"
 #include "networkd-util.h"
-#include "netdev/netdev.h"
+#include "resolve-util.h"
 
 #define DHCP_ROUTE_METRIC 1024
 #define IPV4LL_ROUTE_METRIC 2048
@@ -103,7 +103,7 @@ struct Network {
         char *filename;
         char *name;
 
-        struct ether_addr *match_mac;
+        Set *match_mac;
         char **match_path;
         char **match_driver;
         char **match_type;
@@ -126,6 +126,7 @@ struct Network {
         AddressFamilyBoolean dhcp;
         DHCPClientIdentifier dhcp_client_identifier;
         char *dhcp_vendor_class_identifier;
+        char **dhcp_user_class;
         char *dhcp_hostname;
         unsigned dhcp_route_metric;
         uint32_t dhcp_route_table;
@@ -271,27 +272,28 @@ void network_apply_anonymize_if_set(Network *network);
 
 bool network_has_static_ipv6_addresses(Network *network);
 
-int config_parse_netdev(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_domains(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_tunnel(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_dhcp(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_dns(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_dhcp_client_identifier(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_ipv6token(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_ipv6_privacy_extensions(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_timezone(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_dhcp_server_dns(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_radv_dns(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_radv_search_domains(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_dhcp_server_ntp(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_dnssec_negative_trust_anchors(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_dhcp_use_domains(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_lldp_mode(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
-int config_parse_dhcp_route_table(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_ntp(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);
+CONFIG_PARSER_PROTOTYPE(config_parse_netdev);
+CONFIG_PARSER_PROTOTYPE(config_parse_domains);
+CONFIG_PARSER_PROTOTYPE(config_parse_tunnel);
+CONFIG_PARSER_PROTOTYPE(config_parse_dhcp);
+CONFIG_PARSER_PROTOTYPE(config_parse_dns);
+CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_client_identifier);
+CONFIG_PARSER_PROTOTYPE(config_parse_ipv6token);
+CONFIG_PARSER_PROTOTYPE(config_parse_ipv6_privacy_extensions);
+CONFIG_PARSER_PROTOTYPE(config_parse_hostname);
+CONFIG_PARSER_PROTOTYPE(config_parse_timezone);
+CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_server_dns);
+CONFIG_PARSER_PROTOTYPE(config_parse_radv_dns);
+CONFIG_PARSER_PROTOTYPE(config_parse_radv_search_domains);
+CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_server_ntp);
+CONFIG_PARSER_PROTOTYPE(config_parse_dnssec_negative_trust_anchors);
+CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_use_domains);
+CONFIG_PARSER_PROTOTYPE(config_parse_lldp_mode);
+CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_route_table);
+CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_user_class);
+CONFIG_PARSER_PROTOTYPE(config_parse_ntp);
 /* Legacy IPv4LL support */
-int config_parse_ipv4ll(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);
+CONFIG_PARSER_PROTOTYPE(config_parse_ipv4ll);
 
 const struct ConfigPerfItem* network_network_gperf_lookup(const char *key, GPERF_LEN_TYPE length);
 
index 1e3be1f924c568514d093631e27b9d7f44903125..17c961b411408e5da69f4526ba80183a90a6c64a 100644 (file)
@@ -7,6 +7,7 @@
   Copyright 2017 Intel Corporation. All rights reserved.
 ***/
 
+#include "conf-parser.h"
 #include "networkd-address.h"
 #include "networkd-link.h"
 
@@ -23,16 +24,15 @@ struct Prefix {
 
 int prefix_new(Prefix **ret);
 void prefix_free(Prefix *prefix);
-int prefix_new_static(Network *network, const char *filename, unsigned section,
-                      Prefix **ret);
+int prefix_new_static(Network *network, const char *filename, unsigned section, Prefix **ret);
 
 DEFINE_TRIVIAL_CLEANUP_FUNC(Prefix*, prefix_free);
 
-int config_parse_router_prefix_delegation(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_router_preference(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_prefix(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_prefix_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);
-int config_parse_prefix_lifetime(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);
+CONFIG_PARSER_PROTOTYPE(config_parse_router_prefix_delegation);
+CONFIG_PARSER_PROTOTYPE(config_parse_router_preference);
+CONFIG_PARSER_PROTOTYPE(config_parse_prefix);
+CONFIG_PARSER_PROTOTYPE(config_parse_prefix_flags);
+CONFIG_PARSER_PROTOTYPE(config_parse_prefix_lifetime);
 
 int radv_emit_dns(Link *link);
 int radv_configure(Link *link);
index 3c5127bb8871c502aeffa344f79ad4347371e972..a5303dafa1a7d8df04a2fd08c32f9a093cac6026 100644 (file)
@@ -310,8 +310,7 @@ int route_add_foreign(
         return route_add_internal(link, &link->routes_foreign, family, dst, dst_prefixlen, tos, priority, table, ret);
 }
 
-int route_add(
-              Link *link,
+int route_add(Link *link,
               int family,
               const union in_addr_union *dst,
               unsigned char dst_prefixlen,
@@ -353,30 +352,29 @@ int route_add(
 }
 
 void route_update(Route *route,
-                 const union in_addr_union *src,
-                 unsigned char src_prefixlen,
-                 const union in_addr_union *gw,
-                 const union in_addr_union *prefsrc,
-                 unsigned char scope,
-                 unsigned char protocol,
-                 unsigned char type) {
+                  const union in_addr_union *src,
+                  unsigned char src_prefixlen,
+                  const union in_addr_union *gw,
+                  const union in_addr_union *prefsrc,
+                  unsigned char scope,
+                  unsigned char protocol,
+                  unsigned char type) {
 
         assert(route);
-        assert(src);
-        assert(gw);
-        assert(prefsrc);
+        assert(src || src_prefixlen == 0);
 
-        route->src = *src;
+        route->src = src ? *src : (union in_addr_union) {};
         route->src_prefixlen = src_prefixlen;
-        route->gw = *gw;
-        route->prefsrc = *prefsrc;
+        route->gw = gw ? *gw : (union in_addr_union) {};
+        route->prefsrc = prefsrc ? *prefsrc : (union in_addr_union) {};
         route->scope = scope;
         route->protocol = protocol;
         route->type = type;
 }
 
 int route_remove(Route *route, Link *link,
-               sd_netlink_message_handler_t callback) {
+                 sd_netlink_message_handler_t callback) {
+
         _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL;
         int r;
 
@@ -677,7 +675,8 @@ int route_configure(
         return 0;
 }
 
-int config_parse_gateway(const char *unit,
+int config_parse_gateway(
+                const char *unit,
                 const char *filename,
                 unsigned line,
                 const char *section,
@@ -722,7 +721,8 @@ int config_parse_gateway(const char *unit,
         return 0;
 }
 
-int config_parse_preferred_src(const char *unit,
+int config_parse_preferred_src(
+                const char *unit,
                 const char *filename,
                 unsigned line,
                 const char *section,
@@ -762,7 +762,8 @@ int config_parse_preferred_src(const char *unit,
         return 0;
 }
 
-int config_parse_destination(const char *unit,
+int config_parse_destination(
+                const char *unit,
                 const char *filename,
                 unsigned line,
                 const char *section,
@@ -817,16 +818,18 @@ int config_parse_destination(const char *unit,
         return 0;
 }
 
-int config_parse_route_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_route_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) {
+
         Network *network = userdata;
         _cleanup_(route_freep) Route *n = NULL;
         uint32_t k;
@@ -855,16 +858,18 @@ int config_parse_route_priority(const char *unit,
         return 0;
 }
 
-int config_parse_route_scope(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_route_scope(
+                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) {
+
         Network *network = userdata;
         _cleanup_(route_freep) Route *n = NULL;
         int r;
@@ -895,16 +900,18 @@ int config_parse_route_scope(const char *unit,
         return 0;
 }
 
-int config_parse_route_table(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_route_table(
+                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_(route_freep) Route *n = NULL;
         Network *network = userdata;
         uint32_t k;
@@ -928,22 +935,23 @@ int config_parse_route_table(const char *unit,
         }
 
         n->table = k;
-
         n = NULL;
 
         return 0;
 }
 
-int config_parse_gateway_onlink(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_gateway_onlink(
+                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) {
+
         Network *network = userdata;
         _cleanup_(route_freep) Route *n = NULL;
         int r;
@@ -971,16 +979,18 @@ int config_parse_gateway_onlink(const char *unit,
         return 0;
 }
 
-int config_parse_ipv6_route_preference(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_ipv6_route_preference(
+                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) {
+
         Network *network = userdata;
         _cleanup_(route_freep) Route *n = NULL;
         int r;
@@ -1005,16 +1015,18 @@ int config_parse_ipv6_route_preference(const char *unit,
         return 0;
 }
 
-int config_parse_route_protocol(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_route_protocol(
+                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) {
+
         Network *network = userdata;
         _cleanup_(route_freep) Route *n = NULL;
         int r;
@@ -1042,16 +1054,18 @@ int config_parse_route_protocol(const char *unit,
         return 0;
 }
 
-int config_parse_route_type(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_route_type(
+                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) {
+
         Network *network = userdata;
         _cleanup_(route_freep) Route *n = NULL;
         int r;
@@ -1078,16 +1092,18 @@ int config_parse_route_type(const char *unit,
         return 0;
 }
 
-int config_parse_tcp_window(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_tcp_window(
+                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_(route_freep) Route *n = NULL;
         Network *network = userdata;
         uint64_t k;
@@ -1124,16 +1140,18 @@ int config_parse_tcp_window(const char *unit,
         return 0;
 }
 
-int config_parse_quickack(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_quickack(
+                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_(route_freep) Route *n = NULL;
         Network *network = userdata;
         int k, r;
@@ -1159,3 +1177,38 @@ int config_parse_quickack(const char *unit,
 
         return 0;
 }
+
+int config_parse_route_mtu(
+                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) {
+
+        Network *network = userdata;
+        _cleanup_(route_freep) Route *n = NULL;
+        int r;
+
+        assert(filename);
+        assert(section);
+        assert(lvalue);
+        assert(rvalue);
+        assert(data);
+
+        r = route_new_static(network, filename, section_line, &n);
+        if (r < 0)
+                return r;
+
+        r = config_parse_mtu(unit, filename, line, section, section_line, lvalue, ltype, rvalue, &n->mtu, userdata);
+        if (r < 0)
+                return r;
+
+        n = NULL;
+
+        return 0;
+}
index cda6d582050804495e7672d65fd38b8532888755..61a81b4150f313c6fe8bc593b313cbed133c752a 100644 (file)
@@ -7,6 +7,8 @@
   Copyright 2013 Tom Gundersen <teg@jklm.no>
 ***/
 
+#include "conf-parser.h"
+
 typedef struct Route Route;
 typedef struct NetworkConfigSection NetworkConfigSection;
 
@@ -61,15 +63,16 @@ int route_expire_handler(sd_event_source *s, uint64_t usec, void *userdata);
 
 DEFINE_TRIVIAL_CLEANUP_FUNC(Route*, route_free);
 
-int config_parse_gateway(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_preferred_src(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_destination(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_route_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_route_scope(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_route_table(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_gateway_onlink(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_ipv6_route_preference(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_route_protocol(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_route_type(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_tcp_window(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_quickack(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);
+CONFIG_PARSER_PROTOTYPE(config_parse_gateway);
+CONFIG_PARSER_PROTOTYPE(config_parse_preferred_src);
+CONFIG_PARSER_PROTOTYPE(config_parse_destination);
+CONFIG_PARSER_PROTOTYPE(config_parse_route_priority);
+CONFIG_PARSER_PROTOTYPE(config_parse_route_scope);
+CONFIG_PARSER_PROTOTYPE(config_parse_route_table);
+CONFIG_PARSER_PROTOTYPE(config_parse_gateway_onlink);
+CONFIG_PARSER_PROTOTYPE(config_parse_ipv6_route_preference);
+CONFIG_PARSER_PROTOTYPE(config_parse_route_protocol);
+CONFIG_PARSER_PROTOTYPE(config_parse_route_type);
+CONFIG_PARSER_PROTOTYPE(config_parse_tcp_window);
+CONFIG_PARSER_PROTOTYPE(config_parse_quickack);
+CONFIG_PARSER_PROTOTYPE(config_parse_route_mtu);
index f176d9a088619b82f9dafef2a3ebeedee91eb9d6..98d2eeb0e52c4927aef24f7c0d0d798daf57c460 100644 (file)
@@ -11,6 +11,7 @@
 #include <stdbool.h>
 
 #include "in-addr-util.h"
+#include "conf-parser.h"
 
 typedef struct RoutingPolicyRule RoutingPolicyRule;
 
@@ -69,9 +70,9 @@ int routing_policy_serialize_rules(Set *rules, FILE *f);
 int routing_policy_load_rules(const char *state_file, Set **rules);
 void routing_policy_rule_purge(Manager *m, Link *link);
 
-int config_parse_routing_policy_rule_tos(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_routing_policy_rule_table(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_routing_policy_rule_fwmark_mask(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_routing_policy_rule_prefix(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_routing_policy_rule_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_routing_policy_rule_device(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);
+CONFIG_PARSER_PROTOTYPE(config_parse_routing_policy_rule_tos);
+CONFIG_PARSER_PROTOTYPE(config_parse_routing_policy_rule_table);
+CONFIG_PARSER_PROTOTYPE(config_parse_routing_policy_rule_fwmark_mask);
+CONFIG_PARSER_PROTOTYPE(config_parse_routing_policy_rule_prefix);
+CONFIG_PARSER_PROTOTYPE(config_parse_routing_policy_rule_priority);
+CONFIG_PARSER_PROTOTYPE(config_parse_routing_policy_rule_device);
index 1468ec065485c8e1e136ee7b75f0c8ebb4d5cb88..4e338d0af7bfd5588747a939fac086ea95bfe726 100644 (file)
@@ -7,6 +7,7 @@
   Copyright 2013 Tom Gundersen <teg@jklm.no>
 ***/
 
+#include "conf-parser.h"
 #include "macro.h"
 
 typedef enum AddressFamilyBoolean {
@@ -19,8 +20,8 @@ typedef enum AddressFamilyBoolean {
         _ADDRESS_FAMILY_BOOLEAN_INVALID = -1,
 } AddressFamilyBoolean;
 
-int config_parse_address_family_boolean(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_address_family_boolean_with_kernel(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);
+CONFIG_PARSER_PROTOTYPE(config_parse_address_family_boolean);
+CONFIG_PARSER_PROTOTYPE(config_parse_address_family_boolean_with_kernel);
 
 const char *address_family_boolean_to_string(AddressFamilyBoolean b) _const_;
 AddressFamilyBoolean address_family_boolean_from_string(const char *s) _const_;
index b966fbd96092cacf911a0fb9bb3eec32712b6b9f..87d9aca8f4c6a52cce45895d705bdfe0eba08130 100644 (file)
@@ -5,15 +5,16 @@
   Copyright 2016 Zbigniew Jędrzejewski-Szmek
 ***/
 
+#include "ether-addr-util.h"
 #include "hexdecoct.h"
 #include "log.h"
 #include "macro.h"
+#include "set.h"
 #include "string-util.h"
-#include "ether-addr-util.h"
 
+#include "network-internal.h"
 #include "networkd-conf.h"
 #include "networkd-network.h"
-#include "network-internal.h"
 
 static void test_config_parse_duid_type_one(const char *rvalue, int ret, DUIDType expected) {
         DUIDType actual = 0;
@@ -58,13 +59,29 @@ static void test_config_parse_hwaddr_one(const char *rvalue, int ret, const stru
         assert_se(ret == r);
         if (expected) {
                 assert_se(actual);
-                assert(ether_addr_equal(expected, actual));
-        } else {
+                assert_se(ether_addr_equal(expected, actual));
+        } else
                 assert_se(actual == NULL);
-        }
+
         free(actual);
 }
 
+static void test_config_parse_hwaddrs_one(const char *rvalue, const struct ether_addr* list, size_t n) {
+        _cleanup_set_free_free_ Set *s = NULL;
+        size_t m;
+
+        assert_se(config_parse_hwaddrs("network", "filename", 1, "section", 1, "lvalue", 0, rvalue, &s, NULL) == 0);
+        assert_se(set_size(s) == n);
+
+        for (m = 0; m < n; m++) {
+                _cleanup_free_ struct ether_addr *q = NULL;
+
+                assert_se(q = set_remove(s, &list[m]));
+        }
+
+        assert_se(set_size(s) == 0);
+}
+
 #define BYTES_0_128 "0:1:2:3:4:5:6:7:8:9:a:b:c:d:e:f:10:11:12:13:14:15:16:17:18:19:1a:1b:1c:1d:1e:1f:20:21:22:23:24:25:26:27:28:29:2a:2b:2c:2d:2e:2f:30:31:32:33:34:35:36:37:38:39:3a:3b:3c:3d:3e:3f:40:41:42:43:44:45:46:47:48:49:4a:4b:4c:4d:4e:4f:50:51:52:53:54:55:56:57:58:59:5a:5b:5c:5d:5e:5f:60:61:62:63:64:65:66:67:68:69:6a:6b:6c:6d:6e:6f:70:71:72:73:74:75:76:77:78:79:7a:7b:7c:7d:7e:7f:80"
 
 #define BYTES_1_128 {0x1,0x2,0x3,0x4,0x5,0x6,0x7,0x8,0x9,0xa,0xb,0xc,0xd,0xe,0xf,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f,0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5a,0x5b,0x5c,0x5d,0x5e,0x5f,0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7a,0x7b,0x7c,0x7d,0x7e,0x7f,0x80}
@@ -90,12 +107,13 @@ static void test_config_parse_hwaddr(void) {
                 { .ether_addr_octet = { 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff } },
                 { .ether_addr_octet = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab } },
         };
+
         test_config_parse_hwaddr_one("", 0, NULL);
         test_config_parse_hwaddr_one("no:ta:ma:ca:dd:re", 0, NULL);
         test_config_parse_hwaddr_one("aa:bb:cc:dd:ee:fx", 0, NULL);
         test_config_parse_hwaddr_one("aa:bb:cc:dd:ee:ff", 0, &t[0]);
         test_config_parse_hwaddr_one(" aa:bb:cc:dd:ee:ff", 0, &t[0]);
-        test_config_parse_hwaddr_one("aa:bb:cc:dd:ee:ff \t\n", 0, &t[0]);
+        test_config_parse_hwaddr_one("aa:bb:cc:dd:ee:ff \t\n", 0, NULL);
         test_config_parse_hwaddr_one("aa:bb:cc:dd:ee:ff \t\nxxx", 0, NULL);
         test_config_parse_hwaddr_one("aa:bb:cc: dd:ee:ff", 0, NULL);
         test_config_parse_hwaddr_one("aa:bb:cc:d d:ee:ff", 0, NULL);
@@ -116,6 +134,36 @@ static void test_config_parse_hwaddr(void) {
         test_config_parse_hwaddr_one("aabbccddee:ff", 0, NULL);
         test_config_parse_hwaddr_one("012345.6789ab", 0, NULL);
         test_config_parse_hwaddr_one("123.4567.89ab", 0, &t[1]);
+
+        test_config_parse_hwaddrs_one("", t, 0);
+        test_config_parse_hwaddrs_one("no:ta:ma:ca:dd:re", t, 0);
+        test_config_parse_hwaddrs_one("aa:bb:cc:dd:ee:fx", t, 0);
+        test_config_parse_hwaddrs_one("aa:bb:cc:dd:ee:ff", t, 1);
+        test_config_parse_hwaddrs_one(" aa:bb:cc:dd:ee:ff", t, 1);
+        test_config_parse_hwaddrs_one("aa:bb:cc:dd:ee:ff \t\n", t, 1);
+        test_config_parse_hwaddrs_one("aa:bb:cc:dd:ee:ff \t\nxxx", t, 1);
+        test_config_parse_hwaddrs_one("aa:bb:cc: dd:ee:ff", t, 0);
+        test_config_parse_hwaddrs_one("aa:bb:cc:d d:ee:ff", t, 0);
+        test_config_parse_hwaddrs_one("aa:bb:cc:dd:ee", t, 0);
+        test_config_parse_hwaddrs_one("9:aa:bb:cc:dd:ee:ff", t, 0);
+        test_config_parse_hwaddrs_one("aa:bb:cc:dd:ee:ff:gg", t, 0);
+        test_config_parse_hwaddrs_one("aa:Bb:CC:dd:ee:ff", t, 1);
+        test_config_parse_hwaddrs_one("01:23:45:67:89:aB", &t[1], 1);
+        test_config_parse_hwaddrs_one("1:23:45:67:89:aB", &t[1], 1);
+        test_config_parse_hwaddrs_one("aa-bb-cc-dd-ee-ff", t, 1);
+        test_config_parse_hwaddrs_one("AA-BB-CC-DD-EE-FF", t, 1);
+        test_config_parse_hwaddrs_one("01-23-45-67-89-ab", &t[1], 1);
+        test_config_parse_hwaddrs_one("aabb.ccdd.eeff", t, 1);
+        test_config_parse_hwaddrs_one("0123.4567.89ab", &t[1], 1);
+        test_config_parse_hwaddrs_one("123.4567.89ab.", t, 0);
+        test_config_parse_hwaddrs_one("aabbcc.ddeeff", t, 0);
+        test_config_parse_hwaddrs_one("aabbccddeeff", t, 0);
+        test_config_parse_hwaddrs_one("aabbccddee:ff", t, 0);
+        test_config_parse_hwaddrs_one("012345.6789ab", t, 0);
+        test_config_parse_hwaddrs_one("123.4567.89ab", &t[1], 1);
+
+        test_config_parse_hwaddrs_one("123.4567.89ab aa:bb:cc:dd:ee:ff 01-23-45-67-89-ab aa:Bb:CC:dd:ee:ff", t, 2);
+        test_config_parse_hwaddrs_one("123.4567.89ab aa:bb:cc:dd:ee:fx hogehoge 01-23-45-67-89-ab aaaa aa:Bb:CC:dd:ee:ff", t, 2);
 }
 
 int main(int argc, char **argv) {
index 682ea65080c62b4d999e54f2941c5506b89d02f7..761d737dc9d8c044c76b3a11cc3ee056436ca6b4 100644 (file)
@@ -141,44 +141,53 @@ finish:
         return r;
 }
 
-int create_subcgroup(pid_t pid, CGroupUnified unified_requested) {
+int create_subcgroup(pid_t pid, bool keep_unit, CGroupUnified unified_requested) {
         _cleanup_free_ char *cgroup = NULL;
-        const char *child;
-        int r;
         CGroupMask supported;
+        const char *payload;
+        int r;
 
-        /* In the unified hierarchy inner nodes may only contain
-         * subgroups, but not processes. Hence, if we running in the
-         * unified hierarchy and the container does the same, and we
-         * did not create a scope unit for the container move us and
-         * the container into two separate subcgroups. */
-
-        if (unified_requested == CGROUP_UNIFIED_NONE)
-                return 0;
-
-        r = cg_unified_controller(SYSTEMD_CGROUP_CONTROLLER);
-        if (r < 0)
-                return log_error_errno(r, "Failed to determine whether the systemd controller is unified: %m");
-        if (r == 0)
-                return 0;
+        assert(pid > 1);
+
+        /* In the unified hierarchy inner nodes may only contain subgroups, but not processes. Hence, if we running in
+         * the unified hierarchy and the container does the same, and we did not create a scope unit for the container
+         * move us and the container into two separate subcgroups.
+         *
+         * Moreover, container payloads such as systemd try to manage the cgroup they run in in full (i.e. including
+         * its attributes), while the host systemd will only delegate cgroups for children of the cgroup created for a
+         * delegation unit, instead of the cgroup itself. This means, if we'd pass on the cgroup allocated from the
+         * host systemd directly to the payload, the host and payload systemd might fight for the cgroup
+         * attributes. Hence, let's insert an intermediary cgroup to cover that case too.
+         *
+         * Note that we only bother with the main hierarchy here, not with any secondary ones. On the unified setup
+         * that's fine because there's only one hiearchy anyway and controllers are enabled directly on it. On the
+         * legacy setup, this is fine too, since delegation of controllers is generally not safe there, hence we won't
+         * do it. */
 
         r = cg_mask_supported(&supported);
         if (r < 0)
                 return log_error_errno(r, "Failed to determine supported controllers: %m");
 
-        r = cg_pid_get_path(SYSTEMD_CGROUP_CONTROLLER, 0, &cgroup);
+        if (keep_unit)
+                r = cg_pid_get_path(SYSTEMD_CGROUP_CONTROLLER, 0, &cgroup);
+        else
+                r = cg_pid_get_path(SYSTEMD_CGROUP_CONTROLLER, pid, &cgroup);
         if (r < 0)
                 return log_error_errno(r, "Failed to get our control group: %m");
 
-        child = strjoina(cgroup, "/payload");
-        r = cg_create_and_attach(SYSTEMD_CGROUP_CONTROLLER, child, pid);
+        payload = strjoina(cgroup, "/payload");
+        r = cg_create_and_attach(SYSTEMD_CGROUP_CONTROLLER, payload, pid);
         if (r < 0)
-                return log_error_errno(r, "Failed to create %s subcgroup: %m", child);
+                return log_error_errno(r, "Failed to create %s subcgroup: %m", payload);
 
-        child = strjoina(cgroup, "/supervisor");
-        r = cg_create_and_attach(SYSTEMD_CGROUP_CONTROLLER, child, 0);
-        if (r < 0)
-                return log_error_errno(r, "Failed to create %s subcgroup: %m", child);
+        if (keep_unit) {
+                const char *supervisor;
+
+                supervisor = strjoina(cgroup, "/supervisor");
+                r = cg_create_and_attach(SYSTEMD_CGROUP_CONTROLLER, supervisor, 0);
+                if (r < 0)
+                        return log_error_errno(r, "Failed to create %s subcgroup: %m", supervisor);
+        }
 
         /* Try to enable as many controllers as possible for the new payload. */
         (void) cg_enable_everywhere(supported, supported, cgroup);
index 3a8e98e12216e72ecfc7a519880b9ddae159fd53..7639b483ae79d9a8b52d95a494b28322902d7271 100644 (file)
@@ -14,4 +14,4 @@
 
 int chown_cgroup(pid_t pid, CGroupUnified unified_requested, uid_t uid_shift);
 int sync_cgroup(pid_t pid, CGroupUnified unified_requested, uid_t uid_shift);
-int create_subcgroup(pid_t pid, CGroupUnified unified_requested);
+int create_subcgroup(pid_t pid, bool keep_unit, CGroupUnified unified_requested);
index ea66971fac710b42cdfaeece952a219641ccef74..6029686ee9a7f8d70fd38669c0d2f27005c0fe0a 100644 (file)
@@ -18,35 +18,58 @@ 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
+Exec.ResolvConf,              config_parse_resolv_conf,    0,                 offsetof(Settings, resolv_conf)
+Exec.LinkJournal,             config_parse_link_journal,   0,                 0
+Exec.Timezone,                config_parse_timezone,       0,                 offsetof(Settings, timezone)
+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 1cc4a2da6b8a9092855d31edc0a9e8a123abcbc0..8a4634f53e93821c74119732efd8eef506679928 100644 (file)
@@ -27,7 +27,7 @@
 #include "user-util.h"
 #include "util.h"
 
-CustomMount* custom_mount_add(CustomMount **l, unsigned *n, CustomMountType t) {
+CustomMount* custom_mount_add(CustomMount **l, size_t *n, CustomMountType t) {
         CustomMount *c, *ret;
 
         assert(l);
@@ -48,8 +48,8 @@ CustomMount* custom_mount_add(CustomMount **l, unsigned *n, CustomMountType t) {
         return ret;
 }
 
-void custom_mount_free_all(CustomMount *l, unsigned n) {
-        unsigned i;
+void custom_mount_free_all(CustomMount *l, size_t n) {
+        size_t i;
 
         for (i = 0; i < n; i++) {
                 CustomMount *m = l + i;
@@ -110,8 +110,8 @@ static char *resolve_source_path(const char *dest, const char *source) {
         return strdup(source);
 }
 
-int custom_mount_prepare_all(const char *dest, CustomMount *l, unsigned n) {
-        unsigned i;
+int custom_mount_prepare_all(const char *dest, CustomMount *l, size_t n) {
+        size_t i;
         int r;
 
         /* Prepare all custom mounts. This will make source we know all temporary directories. This is called in the
@@ -133,8 +133,7 @@ int custom_mount_prepare_all(const char *dest, CustomMount *l, unsigned n) {
                         if (!s)
                                 return log_oom();
 
-                        free(m->source);
-                        m->source = s;
+                        free_and_replace(m->source, s);
                 } else {
                         /* No source specified? In that case, use a throw-away temporary directory in /var/tmp */
 
@@ -165,8 +164,7 @@ int custom_mount_prepare_all(const char *dest, CustomMount *l, unsigned n) {
                                 if (!s)
                                         return log_oom();
 
-                                free(*j);
-                                *j = s;
+                                free_and_replace(*j, s);
                         }
 
                         if (m->work_dir) {
@@ -176,8 +174,7 @@ int custom_mount_prepare_all(const char *dest, CustomMount *l, unsigned n) {
                                 if (!s)
                                         return log_oom();
 
-                                free(m->work_dir);
-                                m->work_dir = s;
+                                free_and_replace(m->work_dir, s);
                         } else {
                                 assert(m->source);
 
@@ -193,7 +190,7 @@ int custom_mount_prepare_all(const char *dest, CustomMount *l, unsigned n) {
         return 0;
 }
 
-int bind_mount_parse(CustomMount **l, unsigned *n, const char *s, bool read_only) {
+int bind_mount_parse(CustomMount **l, size_t *n, const char *s, bool read_only) {
         _cleanup_free_ char *source = NULL, *destination = NULL, *opts = NULL;
         const char *p = s;
         CustomMount *m;
@@ -239,7 +236,7 @@ int bind_mount_parse(CustomMount **l, unsigned *n, const char *s, bool read_only
         return 0;
 }
 
-int tmpfs_mount_parse(CustomMount **l, unsigned *n, const char *s) {
+int tmpfs_mount_parse(CustomMount **l, size_t *n, const char *s) {
         _cleanup_free_ char *path = NULL, *opts = NULL;
         const char *p = s;
         CustomMount *m;
@@ -275,7 +272,7 @@ int tmpfs_mount_parse(CustomMount **l, unsigned *n, const char *s) {
         return 0;
 }
 
-int overlay_mount_parse(CustomMount **l, unsigned *n, const char *s, bool read_only) {
+int overlay_mount_parse(CustomMount **l, size_t *n, const char *s, bool read_only) {
         _cleanup_free_ char *upper = NULL, *destination = NULL;
         _cleanup_strv_free_ char **lower = NULL;
         CustomMount *m;
@@ -511,6 +508,18 @@ int mount_all(const char *dest,
               uid_t uid_shift, uid_t uid_range,
               const char *selinux_apifs_context) {
 
+#define PROC_INACCESSIBLE(path)                                         \
+        { NULL, (path), NULL, NULL, MS_BIND,                            \
+          MOUNT_IN_USERNS|MOUNT_APPLY_APIVFS_RO|MOUNT_INACCESSIBLE_REG }, /* Bind mount first ... */ \
+        { NULL, (path), NULL, NULL, MS_BIND|MS_RDONLY|MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_REMOUNT, \
+          MOUNT_IN_USERNS|MOUNT_APPLY_APIVFS_RO } /* Then, make it r/o */
+
+#define PROC_READ_ONLY(path)                                            \
+        { (path), (path), NULL, NULL, MS_BIND,                          \
+          MOUNT_IN_USERNS|MOUNT_APPLY_APIVFS_RO }, /* Bind mount first ... */ \
+        { NULL,   (path), NULL, NULL, MS_BIND|MS_RDONLY|MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_REMOUNT, \
+          MOUNT_IN_USERNS|MOUNT_APPLY_APIVFS_RO } /* Then, make it r/o */
+
         typedef struct MountPoint {
                 const char *what;
                 const char *where;
@@ -521,39 +530,72 @@ int mount_all(const char *dest,
         } MountPoint;
 
         static const MountPoint mount_table[] = {
-                /* inner child mounts */
-                { "proc",                "/proc",               "proc",  NULL,        MS_NOSUID|MS_NOEXEC|MS_NODEV,                              MOUNT_FATAL|MOUNT_IN_USERNS },
-                { "/proc/sys",           "/proc/sys",           NULL,    NULL,        MS_BIND,                                                   MOUNT_FATAL|MOUNT_IN_USERNS|MOUNT_APPLY_APIVFS_RO },                          /* Bind mount first ... */
-                { "/proc/sys/net",       "/proc/sys/net",       NULL,    NULL,        MS_BIND,                                                   MOUNT_FATAL|MOUNT_IN_USERNS|MOUNT_APPLY_APIVFS_RO|MOUNT_APPLY_APIVFS_NETNS }, /* (except for this) */
-                { NULL,                  "/proc/sys",           NULL,    NULL,        MS_BIND|MS_RDONLY|MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_REMOUNT, MOUNT_FATAL|MOUNT_IN_USERNS|MOUNT_APPLY_APIVFS_RO },                          /* ... then, make it r/o */
-                { "/proc/sysrq-trigger", "/proc/sysrq-trigger", NULL,    NULL,        MS_BIND,                                                   MOUNT_IN_USERNS|MOUNT_APPLY_APIVFS_RO },  /* Bind mount first ... */
-                { NULL,                  "/proc/sysrq-trigger", NULL,    NULL,        MS_BIND|MS_RDONLY|MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_REMOUNT, MOUNT_IN_USERNS|MOUNT_APPLY_APIVFS_RO },  /* ... then, make it r/o */
-
-                /* outer child mounts */
-                { "tmpfs",               "/tmp",                "tmpfs", "mode=1777", MS_NOSUID|MS_NODEV|MS_STRICTATIME,                         MOUNT_FATAL },
-                { "tmpfs",               "/sys",                "tmpfs", "mode=755",  MS_NOSUID|MS_NOEXEC|MS_NODEV,                              MOUNT_FATAL|MOUNT_APPLY_APIVFS_NETNS },
-                { "sysfs",               "/sys",                "sysfs", NULL,        MS_RDONLY|MS_NOSUID|MS_NOEXEC|MS_NODEV,                    MOUNT_FATAL|MOUNT_APPLY_APIVFS_RO },    /* skipped if above was mounted */
-                { "sysfs",               "/sys",                "sysfs", NULL,        MS_NOSUID|MS_NOEXEC|MS_NODEV,                              MOUNT_FATAL },                          /* skipped if above was mounted */
-
-                { "tmpfs",               "/dev",                "tmpfs", "mode=755",  MS_NOSUID|MS_STRICTATIME,                                  MOUNT_FATAL },
-                { "tmpfs",               "/dev/shm",            "tmpfs", "mode=1777", MS_NOSUID|MS_NODEV|MS_STRICTATIME,                         MOUNT_FATAL },
-                { "tmpfs",               "/run",                "tmpfs", "mode=755",  MS_NOSUID|MS_NODEV|MS_STRICTATIME,                         MOUNT_FATAL },
+                /* First we list inner child mounts (i.e. mounts applied *after* entering user namespacing) */
+                { "proc",            "/proc",           "proc",  NULL,        MS_NOSUID|MS_NOEXEC|MS_NODEV,
+                  MOUNT_FATAL|MOUNT_IN_USERNS },
+
+                { "/proc/sys",       "/proc/sys",       NULL,    NULL,        MS_BIND,
+                  MOUNT_FATAL|MOUNT_IN_USERNS|MOUNT_APPLY_APIVFS_RO },                          /* Bind mount first ... */
+
+                { "/proc/sys/net",   "/proc/sys/net",   NULL,    NULL,        MS_BIND,
+                  MOUNT_FATAL|MOUNT_IN_USERNS|MOUNT_APPLY_APIVFS_RO|MOUNT_APPLY_APIVFS_NETNS }, /* (except for this) */
+
+                { NULL,              "/proc/sys",       NULL,    NULL,        MS_BIND|MS_RDONLY|MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_REMOUNT,
+                  MOUNT_FATAL|MOUNT_IN_USERNS|MOUNT_APPLY_APIVFS_RO },                          /* ... then, make it r/o */
+
+                /* Make these files inaccessible to container payloads: they potentially leak information about kernel
+                 * internals or the host's execution environment to the container */
+                PROC_INACCESSIBLE("/proc/kallsyms"),
+                PROC_INACCESSIBLE("/proc/kcore"),
+                PROC_INACCESSIBLE("/proc/keys"),
+                PROC_INACCESSIBLE("/proc/sysrq-trigger"),
+                PROC_INACCESSIBLE("/proc/timer_list"),
+
+                /* Make these directories read-only to container payloads: they show hardware information, and in some
+                 * cases contain tunables the container really shouldn't have access to. */
+                PROC_READ_ONLY("/proc/acpi"),
+                PROC_READ_ONLY("/proc/apm"),
+                PROC_READ_ONLY("/proc/asound"),
+                PROC_READ_ONLY("/proc/bus"),
+                PROC_READ_ONLY("/proc/fs"),
+                PROC_READ_ONLY("/proc/irq"),
+                PROC_READ_ONLY("/proc/scsi"),
+
+                /* Then we list outer child mounts (i.e. mounts applied *before* entering user namespacing) */
+                { "tmpfs",           "/tmp",            "tmpfs", "mode=1777", MS_NOSUID|MS_NODEV|MS_STRICTATIME,
+                  MOUNT_FATAL },
+                { "tmpfs",           "/sys",            "tmpfs", "mode=755",  MS_NOSUID|MS_NOEXEC|MS_NODEV,
+                  MOUNT_FATAL|MOUNT_APPLY_APIVFS_NETNS },
+                { "sysfs",           "/sys",            "sysfs", NULL,        MS_RDONLY|MS_NOSUID|MS_NOEXEC|MS_NODEV,
+                  MOUNT_FATAL|MOUNT_APPLY_APIVFS_RO },    /* skipped if above was mounted */
+                { "sysfs",           "/sys",            "sysfs", NULL,        MS_NOSUID|MS_NOEXEC|MS_NODEV,
+                  MOUNT_FATAL },                          /* skipped if above was mounted */
+                { "tmpfs",           "/dev",            "tmpfs", "mode=755",  MS_NOSUID|MS_STRICTATIME,
+                  MOUNT_FATAL },
+                { "tmpfs",           "/dev/shm",        "tmpfs", "mode=1777", MS_NOSUID|MS_NODEV|MS_STRICTATIME,
+                  MOUNT_FATAL },
+                { "tmpfs",           "/run",            "tmpfs", "mode=755",  MS_NOSUID|MS_NODEV|MS_STRICTATIME,
+                  MOUNT_FATAL },
+
 #if HAVE_SELINUX
-                { "/sys/fs/selinux",     "/sys/fs/selinux",     NULL,    NULL,        MS_BIND,                                                   0 },  /* Bind mount first */
-                { NULL,                  "/sys/fs/selinux",     NULL,    NULL,        MS_BIND|MS_RDONLY|MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_REMOUNT, 0 },  /* Then, make it r/o */
+                { "/sys/fs/selinux", "/sys/fs/selinux", NULL,    NULL,        MS_BIND,
+                  0 },  /* Bind mount first */
+                { NULL,              "/sys/fs/selinux", NULL,    NULL,        MS_BIND|MS_RDONLY|MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_REMOUNT,
+                  0 },  /* Then, make it r/o */
 #endif
         };
 
-        unsigned k;
-        int r;
+        _cleanup_(unlink_and_freep) char *inaccessible = NULL;
         bool use_userns = (mount_settings & MOUNT_USE_USERNS);
         bool netns = (mount_settings & MOUNT_APPLY_APIVFS_NETNS);
         bool ro = (mount_settings & MOUNT_APPLY_APIVFS_RO);
         bool in_userns = (mount_settings & MOUNT_IN_USERNS);
+        size_t k;
+        int r;
 
         for (k = 0; k < ELEMENTSOF(mount_table); k++) {
                 _cleanup_free_ char *where = NULL, *options = NULL;
-                const char *o;
+                const char *o, *what;
                 bool fatal = (mount_table[k].mount_settings & MOUNT_FATAL);
 
                 if (in_userns != (bool)(mount_table[k].mount_settings & MOUNT_IN_USERNS))
@@ -569,12 +611,32 @@ int mount_all(const char *dest,
                 if (r < 0)
                         return log_error_errno(r, "Failed to resolve %s/%s: %m", dest, mount_table[k].where);
 
+                if (mount_table[k].mount_settings & MOUNT_INACCESSIBLE_REG) {
+
+                        if (!inaccessible) {
+                                _cleanup_free_ char *np = NULL;
+
+                                r = tempfn_random_child(NULL, "inaccessible", &np);
+                                if (r < 0)
+                                        return log_error_errno(r, "Failed to generate inaccessible file node path: %m");
+
+                                r = touch_file(np, false, USEC_INFINITY, UID_INVALID, GID_INVALID, 0000);
+                                if (r < 0)
+                                        return log_error_errno(r, "Failed to create inaccessible file node '%s': %m", np);
+
+                                inaccessible = TAKE_PTR(np);
+                        }
+
+                        what = inaccessible;
+                } else
+                        what = mount_table[k].what;
+
                 r = path_is_mount_point(where, NULL, 0);
                 if (r < 0 && r != -ENOENT)
                         return log_error_errno(r, "Failed to detect whether %s is a mount point: %m", where);
 
                 /* Skip this entry if it is not a remount. */
-                if (mount_table[k].what && r > 0)
+                if (what && r > 0)
                         continue;
 
                 r = mkdir_userns_p(dest, where, 0755, mount_settings, uid_shift);
@@ -603,7 +665,7 @@ int mount_all(const char *dest,
                 }
 
                 r = mount_verbose(fatal ? LOG_ERR : LOG_DEBUG,
-                                  mount_table[k].what,
+                                  what,
                                   where,
                                   mount_table[k].type,
                                   mount_table[k].flags,
@@ -766,11 +828,11 @@ static int mount_overlay(const char *dest, CustomMount *m) {
 
 int mount_custom(
                 const char *dest,
-                CustomMount *mounts, unsigned n,
+                CustomMount *mounts, size_t n,
                 bool userns, uid_t uid_shift, uid_t uid_range,
                 const char *selinux_apifs_context) {
 
-        unsigned i;
+        size_t i;
         int r;
 
         assert(dest);
index 6d3aca76a087347d745c8ee22925844552972f21..db7aadc28e9c1bf8860dbffb4a10417a8b6dffc1 100644 (file)
 #include "volatile-util.h"
 
 typedef enum MountSettingsMask {
-        MOUNT_FATAL              = 1 << 0, /* if set, a mount error is considered fatal */
-        MOUNT_USE_USERNS         = 1 << 1, /* if set, mounts are patched considering uid/gid shifts in a user namespace */
-        MOUNT_IN_USERNS          = 1 << 2, /* if set, the mount is executed in the inner child, otherwise in the outer child */
-        MOUNT_APPLY_APIVFS_RO    = 1 << 3, /* if set, /proc/sys, and /sysfs will be mounted read-only, otherwise read-write. */
-        MOUNT_APPLY_APIVFS_NETNS = 1 << 4, /* if set, /proc/sys/net will be mounted read-write.
-                                              Works only if MOUNT_APPLY_APIVFS_RO is also set. */
+        MOUNT_FATAL              = 1U << 0, /* if set, a mount error is considered fatal */
+        MOUNT_USE_USERNS         = 1U << 1, /* if set, mounts are patched considering uid/gid shifts in a user namespace */
+        MOUNT_IN_USERNS          = 1U << 2, /* if set, the mount is executed in the inner child, otherwise in the outer child */
+        MOUNT_APPLY_APIVFS_RO    = 1U << 3, /* if set, /proc/sys, and /sys will be mounted read-only, otherwise read-write. */
+        MOUNT_APPLY_APIVFS_NETNS = 1U << 4, /* if set, /proc/sys/net will be mounted read-write.
+                                               Works only if MOUNT_APPLY_APIVFS_RO is also set. */
+        MOUNT_INACCESSIBLE_REG   = 1U << 5, /* if set, create an inaccessible regular file first and use as bind mount source */
 } MountSettingsMask;
 
 typedef enum CustomMountType {
@@ -40,13 +41,13 @@ typedef struct CustomMount {
         char *rm_rf_tmpdir;
 } CustomMount;
 
-CustomMount* custom_mount_add(CustomMount **l, unsigned *n, CustomMountType t);
-void custom_mount_free_all(CustomMount *l, unsigned n);
-int custom_mount_prepare_all(const char *dest, CustomMount *l, unsigned n);
+CustomMount* custom_mount_add(CustomMount **l, size_t *n, CustomMountType t);
+void custom_mount_free_all(CustomMount *l, size_t n);
+int custom_mount_prepare_all(const char *dest, CustomMount *l, size_t n);
 
-int bind_mount_parse(CustomMount **l, unsigned *n, const char *s, bool read_only);
-int tmpfs_mount_parse(CustomMount **l, unsigned *n, const char *s);
-int overlay_mount_parse(CustomMount **l, unsigned *n, const char *s, bool read_only);
+int bind_mount_parse(CustomMount **l, size_t *n, const char *s, bool read_only);
+int tmpfs_mount_parse(CustomMount **l, size_t *n, const char *s);
+int overlay_mount_parse(CustomMount **l, size_t *n, const char *s, bool read_only);
 
 int mount_all(const char *dest, MountSettingsMask mount_settings, uid_t uid_shift, uid_t uid_range, const char *selinux_apifs_context);
 int mount_sysfs(const char *dest, MountSettingsMask mount_settings);
@@ -54,7 +55,7 @@ int mount_sysfs(const char *dest, MountSettingsMask mount_settings);
 int mount_cgroups(const char *dest, CGroupUnified unified_requested, bool userns, uid_t uid_shift, uid_t uid_range, const char *selinux_apifs_context, bool use_cgns);
 int mount_systemd_cgroup_writable(const char *dest, CGroupUnified unified_requested);
 
-int mount_custom(const char *dest, CustomMount *mounts, unsigned n, bool userns, uid_t uid_shift, uid_t uid_range, const char *selinux_apifs_context);
+int mount_custom(const char *dest, CustomMount *mounts, size_t n, bool userns, uid_t uid_shift, uid_t uid_range, const char *selinux_apifs_context);
 
 int setup_volatile(const char *directory, VolatileMode mode, bool userns, uid_t uid_shift, uid_t uid_range, const char *selinux_apifs_context);
 int setup_volatile_state(const char *directory, VolatileMode mode, bool userns, uid_t uid_shift, uid_t uid_range, const char *selinux_apifs_context);
index 643e00400f80d661726c26fb5ab78f3ea1d08731..c0cdb7c0d748b4207a9d7538f05754118fd41a54 100644 (file)
@@ -11,6 +11,7 @@
 #include "bus-unit-util.h"
 #include "bus-util.h"
 #include "nspawn-register.h"
+#include "special.h"
 #include "stat-util.h"
 #include "strv.h"
 #include "util.h"
@@ -309,7 +310,7 @@ int allocate_scope(
                                   "PIDs", "au", 1, pid,
                                   "Description", "s", description,
                                   "Delegate", "b", 1,
-                                  "Slice", "s", isempty(slice) ? "machine.slice" : slice);
+                                  "Slice", "s", isempty(slice) ? SPECIAL_MACHINE_SLICE : slice);
         if (r < 0)
                 return bus_log_create_error(r);
 
index 487514d40a956f4132e7d5fae6fe456cb241cf7c..126335da58229f9cb534e92b5c620b893bab6ce0 100644 (file)
@@ -8,11 +8,15 @@
 #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-table.h"
 #include "string-util.h"
 #include "strv.h"
 #include "user-util.h"
@@ -32,8 +36,12 @@ int settings_load(FILE *f, const char *path, Settings **ret) {
         s->start_mode = _START_MODE_INVALID;
         s->personality = PERSONALITY_INVALID;
         s->userns_mode = _USER_NAMESPACE_MODE_INVALID;
+        s->resolv_conf = _RESOLV_CONF_MODE_INVALID;
+        s->link_journal = _LINK_JOURNAL_INVALID;
+        s->timezone = _TIMEZONE_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 +88,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 +612,202 @@ 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;
+}
+
+DEFINE_CONFIG_PARSE_ENUM(config_parse_resolv_conf, resolv_conf_mode, ResolvConfMode, "Failed to parse resolv.conf mode");
+
+static const char *const resolv_conf_mode_table[_RESOLV_CONF_MODE_MAX] = {
+        [RESOLV_CONF_OFF] = "off",
+        [RESOLV_CONF_COPY_HOST] = "copy-host",
+        [RESOLV_CONF_COPY_STATIC] = "copy-static",
+        [RESOLV_CONF_BIND_HOST] = "bind-host",
+        [RESOLV_CONF_BIND_STATIC] = "bind-static",
+        [RESOLV_CONF_DELETE] = "delete",
+        [RESOLV_CONF_AUTO] = "auto",
+};
+
+DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(resolv_conf_mode, ResolvConfMode, RESOLV_CONF_AUTO);
+
+int parse_link_journal(const char *s, LinkJournal *ret_mode, bool *ret_try) {
+        assert(s);
+        assert(ret_mode);
+        assert(ret_try);
+
+        if (streq(s, "auto")) {
+                *ret_mode = LINK_AUTO;
+                *ret_try = false;
+        } else if (streq(s, "no")) {
+                *ret_mode = LINK_NO;
+                *ret_try = false;
+        } else if (streq(s, "guest")) {
+                *ret_mode = LINK_GUEST;
+                *ret_try = false;
+        } else if (streq(s, "host")) {
+                *ret_mode = LINK_HOST;
+                *ret_try = false;
+        } else if (streq(s, "try-guest")) {
+                *ret_mode = LINK_GUEST;
+                *ret_try = true;
+        } else if (streq(s, "try-host")) {
+                *ret_mode = LINK_HOST;
+                *ret_try = true;
+        } else
+                return -EINVAL;
+
+        return 0;
+}
+
+int config_parse_link_journal(
+                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 r;
+
+        assert(rvalue);
+        assert(settings);
+
+        r = parse_link_journal(rvalue, &settings->link_journal, &settings->link_journal_try);
+        if (r < 0) {
+                log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse link journal mode, ignoring: %s", rvalue);
+                return 0;
+        }
+
+        return 0;
+}
+
+DEFINE_CONFIG_PARSE_ENUM(config_parse_timezone, timezone_mode, TimezoneMode, "Failed to parse timezone mode");
+
+static const char *const timezone_mode_table[_TIMEZONE_MODE_MAX] = {
+        [TIMEZONE_OFF] = "off",
+        [TIMEZONE_COPY] = "copy",
+        [TIMEZONE_BIND] = "bind",
+        [TIMEZONE_SYMLINK] = "symlink",
+        [TIMEZONE_DELETE] = "delete",
+        [TIMEZONE_AUTO] = "auto",
+};
+
+DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(timezone_mode, TimezoneMode, TIMEZONE_AUTO);
index bee7e9f53030353558e08bfdefdb8e5f65a05c21..28a0d8b8e1013867e468363267c21ffaddf5a43a 100644 (file)
@@ -7,10 +7,12 @@
   Copyright 2015 Lennart Poettering
 ***/
 
+#include <sched.h>
 #include <stdio.h>
 
 #include "sd-id128.h"
 
+#include "conf-parser.h"
 #include "macro.h"
 #include "nspawn-expose-ports.h"
 #include "nspawn-mount.h"
@@ -31,27 +33,78 @@ typedef enum UserNamespaceMode {
         _USER_NAMESPACE_MODE_INVALID = -1,
 } UserNamespaceMode;
 
+typedef enum ResolvConfMode {
+        RESOLV_CONF_OFF,
+        RESOLV_CONF_COPY_HOST,
+        RESOLV_CONF_COPY_STATIC,
+        RESOLV_CONF_BIND_HOST,
+        RESOLV_CONF_BIND_STATIC,
+        RESOLV_CONF_DELETE,
+        RESOLV_CONF_AUTO,
+        _RESOLV_CONF_MODE_MAX,
+        _RESOLV_CONF_MODE_INVALID = -1
+} ResolvConfMode;
+
+typedef enum LinkJournal {
+        LINK_NO,
+        LINK_AUTO,
+        LINK_HOST,
+        LINK_GUEST,
+        _LINK_JOURNAL_MAX,
+        _LINK_JOURNAL_INVALID = -1
+} LinkJournal;
+
+typedef enum TimezoneMode {
+        TIMEZONE_OFF,
+        TIMEZONE_COPY,
+        TIMEZONE_BIND,
+        TIMEZONE_SYMLINK,
+        TIMEZONE_DELETE,
+        TIMEZONE_AUTO,
+        _TIMEZONE_MODE_MAX,
+        _TIMEZONE_MODE_INVALID = -1
+} TimezoneMode;
+
 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_RESOLV_CONF       = UINT64_C(1) << 21,
+        SETTING_LINK_JOURNAL      = UINT64_C(1) << 22,
+        SETTING_TIMEZONE          = UINT64_C(1) << 23,
+        SETTING_RLIMIT_FIRST      = UINT64_C(1) << 24, /* we define one bit per resource limit here */
+        SETTING_RLIMIT_LAST       = UINT64_C(1) << (24 + _RLIMIT_MAX - 1),
+        _SETTINGS_MASK_ALL        = (UINT64_C(1) << (24 + _RLIMIT_MAX)) -1,
+        _SETTING_FORCE_ENUM_WIDTH = UINT64_MAX
 } SettingsMask;
 
+/* We want to use SETTING_RLIMIT_FIRST in shifts, so make sure it is really 64 bits
+ * when used in expressions. */
+#define SETTING_RLIMIT_FIRST ((uint64_t) SETTING_RLIMIT_FIRST)
+#define SETTING_RLIMIT_LAST ((uint64_t) SETTING_RLIMIT_LAST)
+
+assert_cc(sizeof(SettingsMask) == 8);
+assert_cc(sizeof(SETTING_RLIMIT_FIRST) == 8);
+assert_cc(sizeof(SETTING_RLIMIT_LAST) == 8);
+
 typedef struct Settings {
         /* [Run] */
         StartMode start_mode;
@@ -71,12 +124,23 @@ 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;
+        ResolvConfMode resolv_conf;
+        LinkJournal link_journal;
+        bool link_journal_try;
+        TimezoneMode timezone;
 
         /* [Image] */
         int read_only;
         VolatileMode volatile_mode;
         CustomMount *custom_mounts;
-        unsigned n_custom_mounts;
+        size_t n_custom_mounts;
         int userns_chown;
 
         /* [Network] */
@@ -101,17 +165,31 @@ DEFINE_TRIVIAL_CLEANUP_FUNC(Settings*, settings_free);
 
 const struct ConfigPerfItem* nspawn_gperf_lookup(const char *key, GPERF_LEN_TYPE length);
 
-int config_parse_capability(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_id128(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_expose_port(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_volatile_mode(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
-int config_parse_pivot_root(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_bind(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_tmpfs(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_overlay(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_veth_extra(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_network_zone(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_boot(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_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);
+CONFIG_PARSER_PROTOTYPE(config_parse_capability);
+CONFIG_PARSER_PROTOTYPE(config_parse_id128);
+CONFIG_PARSER_PROTOTYPE(config_parse_expose_port);
+CONFIG_PARSER_PROTOTYPE(config_parse_volatile_mode);
+CONFIG_PARSER_PROTOTYPE(config_parse_pivot_root);
+CONFIG_PARSER_PROTOTYPE(config_parse_bind);
+CONFIG_PARSER_PROTOTYPE(config_parse_tmpfs);
+CONFIG_PARSER_PROTOTYPE(config_parse_overlay);
+CONFIG_PARSER_PROTOTYPE(config_parse_veth_extra);
+CONFIG_PARSER_PROTOTYPE(config_parse_network_zone);
+CONFIG_PARSER_PROTOTYPE(config_parse_boot);
+CONFIG_PARSER_PROTOTYPE(config_parse_pid2);
+CONFIG_PARSER_PROTOTYPE(config_parse_private_users);
+CONFIG_PARSER_PROTOTYPE(config_parse_syscall_filter);
+CONFIG_PARSER_PROTOTYPE(config_parse_hostname);
+CONFIG_PARSER_PROTOTYPE(config_parse_oom_score_adjust);
+CONFIG_PARSER_PROTOTYPE(config_parse_cpu_affinity);
+CONFIG_PARSER_PROTOTYPE(config_parse_resolv_conf);
+CONFIG_PARSER_PROTOTYPE(config_parse_link_journal);
+CONFIG_PARSER_PROTOTYPE(config_parse_timezone);
+
+const char *resolv_conf_mode_to_string(ResolvConfMode a) _const_;
+ResolvConfMode resolv_conf_mode_from_string(const char *s) _pure_;
+
+const char *timezone_mode_to_string(TimezoneMode a) _const_;
+TimezoneMode timezone_mode_from_string(const char *s) _pure_;
+
+int parse_link_journal(const char *s, LinkJournal *ret_mode, bool *ret_try);
index 23bc9402a8af22be1f779c3f8d3a6bc6868ee2aa..009ecf4e4a1a468864ad782eb948e682f39f2dcd 100644 (file)
 #include "base-filesystem.h"
 #include "blkid-util.h"
 #include "btrfs-util.h"
+#include "bus-error.h"
 #include "bus-util.h"
 #include "cap-list.h"
 #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"
 #include "socket-util.h"
 #include "stat-util.h"
 #include "stdio-util.h"
+#include "string-table.h"
 #include "string-util.h"
 #include "strv.h"
 #include "terminal-util.h"
@@ -113,13 +118,6 @@ typedef enum ContainerStatus {
         CONTAINER_REBOOTED
 } ContainerStatus;
 
-typedef enum LinkJournal {
-        LINK_NO,
-        LINK_AUTO,
-        LINK_HOST,
-        LINK_GUEST
-} LinkJournal;
-
 static char *arg_directory = NULL;
 static char *arg_template = NULL;
 static char *arg_chdir = NULL;
@@ -127,7 +125,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;
@@ -165,7 +164,7 @@ static uint64_t arg_caps_retain =
         (1ULL << CAP_SYS_RESOURCE) |
         (1ULL << CAP_SYS_TTY_CONFIG);
 static CustomMount *arg_custom_mounts = NULL;
-static unsigned arg_n_custom_mounts = 0;
+static size_t arg_n_custom_mounts = 0;
 static char **arg_setenv = NULL;
 static bool arg_quiet = false;
 static bool arg_register = true;
@@ -200,8 +199,19 @@ 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 ResolvConfMode arg_resolv_conf = RESOLV_CONF_AUTO;
+static TimezoneMode arg_timezone = TIMEZONE_AUTO;
 
 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 +231,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,10 +275,16 @@ 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"
                "  -j                        Equivalent to --link-journal=try-guest\n"
+               "     --resolv-conf=MODE     Select mode of /etc/resolv.conf initialization\n"
+               "     --timezone=MODE        Select mode of /etc/localtime initialization\n"
                "     --read-only            Mount the root directory read-only\n"
                "     --bind=PATH[:PATH[:OPTIONS]]\n"
                "                            Bind mount a file or directory from the host into\n"
@@ -291,7 +308,7 @@ static void help(void) {
 }
 
 static int custom_mount_check_all(void) {
-        unsigned i;
+        size_t i;
 
         for (i = 0; i < arg_n_custom_mounts; i++) {
                 CustomMount *m = &arg_custom_mounts[i];
@@ -439,6 +456,13 @@ 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,
+                ARG_RESOLV_CONF,
+                ARG_TIMEZONE,
         };
 
         static const struct option options[] = {
@@ -455,6 +479,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 +487,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 +518,11 @@ 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           },
+                { "resolv-conf",            required_argument, NULL, ARG_RESOLV_CONF            },
+                { "timezone",               required_argument, NULL, ARG_TIMEZONE               },
                 {}
         };
 
@@ -696,6 +727,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,35 +795,29 @@ 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;
+                        arg_settings_mask |= SETTING_LINK_JOURNAL;
                         break;
 
                 case ARG_LINK_JOURNAL:
-                        if (streq(optarg, "auto")) {
-                                arg_link_journal = LINK_AUTO;
-                                arg_link_journal_try = false;
-                        } else if (streq(optarg, "no")) {
-                                arg_link_journal = LINK_NO;
-                                arg_link_journal_try = false;
-                        } else if (streq(optarg, "guest")) {
-                                arg_link_journal = LINK_GUEST;
-                                arg_link_journal_try = false;
-                        } else if (streq(optarg, "host")) {
-                                arg_link_journal = LINK_HOST;
-                                arg_link_journal_try = false;
-                        } else if (streq(optarg, "try-guest")) {
-                                arg_link_journal = LINK_GUEST;
-                                arg_link_journal_try = true;
-                        } else if (streq(optarg, "try-host")) {
-                                arg_link_journal = LINK_HOST;
-                                arg_link_journal_try = true;
-                        } else {
-                                log_error("Failed to parse link journal mode %s", optarg);
+                        r = parse_link_journal(optarg, &arg_link_journal, &arg_link_journal_try);
+                        if (r < 0) {
+                                log_error_errno(r, "Failed to parse link journal mode %s", optarg);
                                 return -EINVAL;
                         }
 
+                        arg_settings_mask |= SETTING_LINK_JOURNAL;
                         break;
 
                 case ARG_BIND:
@@ -818,9 +860,7 @@ static int parse_argv(int argc, char *argv[]) {
                         if (!n)
                                 return log_oom();
 
-                        strv_free(arg_setenv);
-                        arg_setenv = n;
-
+                        strv_free_and_replace(arg_setenv, n);
                         arg_settings_mask |= SETTING_ENVIRONMENT;
                         break;
                 }
@@ -832,6 +872,7 @@ static int parse_argv(int argc, char *argv[]) {
                 case ARG_SHARE_SYSTEM:
                         /* We don't officially support this anymore, except for compat reasons. People should use the
                          * $SYSTEMD_NSPAWN_SHARE_* environment variables instead. */
+                        log_warning("Please do not use --share-system anymore, use $SYSTEMD_NSPAWN_SHARE_* instead.");
                         arg_clone_ns_flags = 0;
                         break;
 
@@ -864,7 +905,10 @@ static int parse_argv(int argc, char *argv[]) {
 
                         if (!optarg)
                                 arg_volatile_mode = VOLATILE_YES;
-                        else {
+                        else if (streq(optarg, "help")) {
+                                DUMP_STRING_TABLE(volatile_mode, VolatileMode, _VOLATILE_MODE_MAX);
+                                return 0;
+                        } else {
                                 VolatileMode m;
 
                                 m = volatile_mode_from_string(optarg);
@@ -972,6 +1016,11 @@ static int parse_argv(int argc, char *argv[]) {
                         break;
 
                 case ARG_KILL_SIGNAL:
+                        if (streq(optarg, "help")) {
+                                DUMP_STRING_TABLE(signal, int, _NSIG);
+                                return 0;
+                        }
+
                         arg_kill_signal = signal_from_string(optarg);
                         if (arg_kill_signal < 0) {
                                 log_error("Cannot parse signal: %s", optarg);
@@ -1096,6 +1145,101 @@ static int parse_argv(int argc, char *argv[]) {
                         break;
                 }
 
+                case ARG_RLIMIT: {
+                        const char *eq;
+                        char *name;
+                        int rl;
+
+                        if (streq(optarg, "help")) {
+                                DUMP_STRING_TABLE(rlimit, int, _RLIMIT_MAX);
+                                return 0;
+                        }
+
+                        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 ARG_RESOLV_CONF:
+                        if (streq(optarg, "help")) {
+                                DUMP_STRING_TABLE(resolv_conf_mode, ResolvConfMode, _RESOLV_CONF_MODE_MAX);
+                                return 0;
+                        }
+
+                        arg_resolv_conf = resolv_conf_mode_from_string(optarg);
+                        if (arg_resolv_conf < 0) {
+                                log_error("Failed to parse /etc/resolv.conf mode: %s", optarg);
+                                return -EINVAL;
+                        }
+
+                        arg_settings_mask |= SETTING_RESOLV_CONF;
+                        break;
+
+                case ARG_TIMEZONE:
+                        if (streq(optarg, "help")) {
+                                DUMP_STRING_TABLE(timezone_mode, TimezoneMode, _TIMEZONE_MODE_MAX);
+                                return 0;
+                        }
+
+                        arg_timezone = timezone_mode_from_string(optarg);
+                        if (arg_timezone < 0) {
+                                log_error("Failed to parse /etc/localtime mode: %s", optarg);
+                                return -EINVAL;
+                        }
+
+                        arg_settings_mask |= SETTING_TIMEZONE;
+                        break;
+
                 case '?':
                         return -EINVAL;
 
@@ -1311,77 +1455,166 @@ static int userns_mkdir(const char *root, const char *path, mode_t mode, uid_t u
         return userns_lchown(q, uid, gid);
 }
 
+static const char *timezone_from_path(const char *path) {
+        const char *z;
+
+        z = path_startswith(path, "../usr/share/zoneinfo/");
+        if (z)
+                return z;
+
+        z = path_startswith(path, "/usr/share/zoneinfo/");
+        if (z)
+                return z;
+
+        return NULL;
+}
+
 static int setup_timezone(const char *dest) {
-        _cleanup_free_ char *p = NULL, *q = NULL;
-        const char *where, *check, *what;
-        char *z, *y;
+        _cleanup_free_ char *p = NULL, *etc = NULL;
+        const char *where, *check;
+        TimezoneMode m;
         int r;
 
         assert(dest);
 
-        /* Fix the timezone, if possible */
-        r = readlink_malloc("/etc/localtime", &p);
+        if (IN_SET(arg_timezone, TIMEZONE_AUTO, TIMEZONE_SYMLINK)) {
+
+                r = readlink_malloc("/etc/localtime", &p);
+                if (r == -ENOENT && arg_timezone == TIMEZONE_AUTO)
+                        m = arg_read_only && arg_volatile_mode != VOLATILE_YES ? TIMEZONE_OFF : TIMEZONE_DELETE;
+                else if (r == -EINVAL && arg_timezone == TIMEZONE_AUTO) /* regular file? */
+                        m = arg_read_only && arg_volatile_mode != VOLATILE_YES ? TIMEZONE_BIND : TIMEZONE_COPY;
+                else if (r < 0) {
+                        log_warning_errno(r, "Failed to read host's /etc/localtime symlink, not updating container timezone: %m");
+                        /* To handle warning, delete /etc/localtime and replace it with a symbolic link to a time zone data
+                         * file.
+                         *
+                         * Example:
+                         * ln -s /usr/share/zoneinfo/UTC /etc/localtime
+                         */
+                        return 0;
+                } else if (arg_timezone == TIMEZONE_AUTO)
+                        m = arg_read_only && arg_volatile_mode != VOLATILE_YES ? TIMEZONE_BIND : TIMEZONE_SYMLINK;
+                else
+                        m = arg_timezone;
+        } else
+                m = arg_timezone;
+
+        if (m == TIMEZONE_OFF)
+                return 0;
+
+        r = chase_symlinks("/etc", dest, CHASE_PREFIX_ROOT, &etc);
         if (r < 0) {
-                log_warning("host's /etc/localtime is not a symlink, not updating container timezone.");
-                /* to handle warning, delete /etc/localtime and replace it
-                 * with a symbolic link to a time zone data file.
-                 *
-                 * Example:
-                 * ln -s /usr/share/zoneinfo/UTC /etc/localtime
-                 */
+                log_warning_errno(r, "Failed to resolve /etc path in container, ignoring: %m");
                 return 0;
         }
 
-        z = path_startswith(p, "../usr/share/zoneinfo/");
-        if (!z)
-                z = path_startswith(p, "/usr/share/zoneinfo/");
-        if (!z) {
-                log_warning("/etc/localtime does not point into /usr/share/zoneinfo/, not updating container timezone.");
+        where = strjoina(etc, "/localtime");
+
+        switch (m) {
+
+        case TIMEZONE_DELETE:
+                if (unlink(where) < 0)
+                        log_full_errno(errno == ENOENT ? LOG_DEBUG : LOG_WARNING, errno, "Failed to remove '%s', ignoring: %m", where);
+
                 return 0;
-        }
 
-        where = prefix_roota(dest, "/etc/localtime");
-        r = readlink_malloc(where, &q);
-        if (r >= 0) {
-                y = path_startswith(q, "../usr/share/zoneinfo/");
-                if (!y)
-                        y = path_startswith(q, "/usr/share/zoneinfo/");
+        case TIMEZONE_SYMLINK: {
+                _cleanup_free_ char *q = NULL;
+                const char *z, *what;
 
-                /* Already pointing to the right place? Then do nothing .. */
-                if (y && streq(y, z))
+                z = timezone_from_path(p);
+                if (!z) {
+                        log_warning("/etc/localtime does not point into /usr/share/zoneinfo/, not updating container timezone.");
                         return 0;
-        }
+                }
 
-        check = strjoina("/usr/share/zoneinfo/", z);
-        check = prefix_roota(dest, check);
-        if (laccess(check, F_OK) < 0) {
-                log_warning("Timezone %s does not exist in container, not updating container timezone.", z);
-                return 0;
+                r = readlink_malloc(where, &q);
+                if (r >= 0 && streq_ptr(timezone_from_path(q), z))
+                        return 0; /* Already pointing to the right place? Then do nothing .. */
+
+                check = strjoina(dest, "/usr/share/zoneinfo/", z);
+                r = chase_symlinks(check, dest, 0, NULL);
+                if (r < 0)
+                        log_debug_errno(r, "Timezone %s does not exist (or is not accessible) in container, not creating symlink: %m", z);
+                else {
+                        if (unlink(where) < 0 && errno != ENOENT) {
+                                log_full_errno(IN_SET(errno, EROFS, EACCES, EPERM) ? LOG_DEBUG : LOG_WARNING, /* Don't complain on read-only images */
+                                               errno, "Failed to remove existing timezone info %s in container, ignoring: %m", where);
+                                return 0;
+                        }
+
+                        what = strjoina("../usr/share/zoneinfo/", z);
+                        if (symlink(what, where) < 0) {
+                                log_full_errno(IN_SET(errno, EROFS, EACCES, EPERM) ? LOG_DEBUG : LOG_WARNING,
+                                               errno, "Failed to correct timezone of container, ignoring: %m");
+                                return 0;
+                        }
+
+                        break;
+                }
+
+                _fallthrough_;
         }
 
-        if (unlink(where) < 0 && errno != ENOENT) {
-                log_full_errno(IN_SET(errno, EROFS, EACCES, EPERM) ? LOG_DEBUG : LOG_WARNING, /* Don't complain on read-only images */
-                               errno,
-                               "Failed to remove existing timezone info %s in container, ignoring: %m", where);
-                return 0;
+        case TIMEZONE_BIND: {
+                _cleanup_free_ char *resolved = NULL;
+                int found;
+
+                found = chase_symlinks(where, dest, CHASE_NONEXISTENT, &resolved);
+                if (found < 0) {
+                        log_warning_errno(found, "Failed to resolve /etc/localtime path in container, ignoring: %m");
+                        return 0;
+                }
+
+                if (found == 0) /* missing? */
+                        (void) touch(resolved);
+
+                r = mount_verbose(LOG_WARNING, "/etc/localtime", resolved, NULL, MS_BIND, NULL);
+                if (r >= 0)
+                        return mount_verbose(LOG_ERR, NULL, resolved, NULL, MS_BIND|MS_REMOUNT|MS_RDONLY|MS_NOSUID|MS_NODEV, NULL);
+
+                _fallthrough_;
         }
 
-        what = strjoina("../usr/share/zoneinfo/", z);
-        if (symlink(what, where) < 0) {
-                log_full_errno(IN_SET(errno, EROFS, EACCES, EPERM) ? LOG_DEBUG : LOG_WARNING,
-                               errno,
-                               "Failed to correct timezone of container, ignoring: %m");
-                return 0;
+        case TIMEZONE_COPY:
+                /* If mounting failed, try to copy */
+                r = copy_file_atomic("/etc/localtime", where, 0644, 0, COPY_REFLINK|COPY_REPLACE);
+                if (r < 0) {
+                        log_full_errno(IN_SET(r, -EROFS, -EACCES, -EPERM) ? LOG_DEBUG : LOG_WARNING, r,
+                                       "Failed to copy /etc/localtime to %s, ignoring: %m", where);
+                        return 0;
+                }
+
+                break;
+
+        default:
+                assert_not_reached("unexpected mode");
         }
 
+        /* Fix permissions of the symlink or file copy we just created */
         r = userns_lchown(where, 0, 0);
         if (r < 0)
-                return log_warning_errno(r, "Failed to chown /etc/localtime: %m");
+                log_warning_errno(r, "Failed to chown /etc/localtime, ignoring: %m");
 
         return 0;
 }
 
+static int have_resolv_conf(const char *path) {
+        assert(path);
+
+        if (access(path, F_OK) < 0) {
+                if (errno == ENOENT)
+                        return 0;
+
+                return log_debug_errno(errno, "Failed to determine whether '%s' is available: %m", path);
+        }
+
+        return 1;
+}
+
 static int resolved_listening(void) {
+        _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
         _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
         _cleanup_free_ char *dns_stub_listener_mode = NULL;
         int r;
@@ -1390,33 +1623,53 @@ static int resolved_listening(void) {
 
         r = sd_bus_open_system(&bus);
         if (r < 0)
-                return r;
+                return log_debug_errno(r, "Failed to open system bus: %m");
 
         r = bus_name_has_owner(bus, "org.freedesktop.resolve1", NULL);
-        if (r <= 0)
-                return r;
+        if (r < 0)
+                return log_debug_errno(r, "Failed to check whether the 'org.freedesktop.resolve1' bus name is taken: %m");
+        if (r == 0)
+                return 0;
 
         r = sd_bus_get_property_string(bus,
                                        "org.freedesktop.resolve1",
                                        "/org/freedesktop/resolve1",
                                        "org.freedesktop.resolve1.Manager",
                                        "DNSStubListener",
-                                       NULL,
+                                       &error,
                                        &dns_stub_listener_mode);
         if (r < 0)
-                return r;
+                return log_debug_errno(r, "Failed to query DNSStubListener property: %s", bus_error_message(&error, r));
 
         return STR_IN_SET(dns_stub_listener_mode, "udp", "yes");
 }
 
 static int setup_resolv_conf(const char *dest) {
-        _cleanup_free_ char *resolved = NULL, *etc = NULL;
-        const char *where;
-        int r, found;
+        _cleanup_free_ char *etc = NULL;
+        const char *where, *what;
+        ResolvConfMode m;
+        int r;
 
         assert(dest);
 
-        if (arg_private_network)
+        if (arg_resolv_conf == RESOLV_CONF_AUTO) {
+                if (arg_private_network)
+                        m = RESOLV_CONF_OFF;
+                else if (have_resolv_conf(STATIC_RESOLV_CONF) > 0 && resolved_listening() > 0)
+                        /* resolved is enabled on the host. In this, case bind mount its static resolv.conf file into the
+                         * container, so that the container can use the host's resolver. Given that network namespacing is
+                         * disabled it's only natural of the container also uses the host's resolver. It also has the big
+                         * advantage that the container will be able to follow the host's DNS server configuration changes
+                         * transparently. */
+                        m = RESOLV_CONF_BIND_STATIC;
+                else if (have_resolv_conf("/etc/resolv.conf") > 0)
+                        m = arg_read_only && arg_volatile_mode != VOLATILE_YES ? RESOLV_CONF_BIND_HOST : RESOLV_CONF_COPY_HOST;
+                else
+                        m = arg_read_only && arg_volatile_mode != VOLATILE_YES ? RESOLV_CONF_OFF : RESOLV_CONF_DELETE;
+        } else
+                m = arg_resolv_conf;
+
+        if (m == RESOLV_CONF_OFF)
                 return 0;
 
         r = chase_symlinks("/etc", dest, CHASE_PREFIX_ROOT, &etc);
@@ -1426,38 +1679,46 @@ static int setup_resolv_conf(const char *dest) {
         }
 
         where = strjoina(etc, "/resolv.conf");
-        found = chase_symlinks(where, dest, CHASE_NONEXISTENT, &resolved);
-        if (found < 0) {
-                log_warning_errno(found, "Failed to resolve /etc/resolv.conf path in container, ignoring: %m");
+
+        if (m == RESOLV_CONF_DELETE) {
+                if (unlink(where) < 0)
+                        log_full_errno(errno == ENOENT ? LOG_DEBUG : LOG_WARNING, errno, "Failed to remove '%s', ignoring: %m", where);
+
                 return 0;
         }
 
-        if (access(STATIC_RESOLV_CONF, F_OK) >= 0 &&
-            resolved_listening() > 0) {
+        if (IN_SET(m, RESOLV_CONF_BIND_STATIC, RESOLV_CONF_COPY_STATIC))
+                what = STATIC_RESOLV_CONF;
+        else
+                what = "/etc/resolv.conf";
 
-                /* resolved is enabled on the host. In this, case bind mount its static resolv.conf file into the
-                 * container, so that the container can use the host's resolver. Given that network namespacing is
-                 * disabled it's only natural of the container also uses the host's resolver. It also has the big
-                 * advantage that the container will be able to follow the host's DNS server configuration changes
-                 * transparently. */
+        if (IN_SET(m, RESOLV_CONF_BIND_HOST, RESOLV_CONF_BIND_STATIC)) {
+                _cleanup_free_ char *resolved = NULL;
+                int found;
+
+                found = chase_symlinks(where, dest, CHASE_NONEXISTENT, &resolved);
+                if (found < 0) {
+                        log_warning_errno(found, "Failed to resolve /etc/resolv.conf path in container, ignoring: %m");
+                        return 0;
+                }
 
                 if (found == 0) /* missing? */
                         (void) touch(resolved);
 
-                r = mount_verbose(LOG_DEBUG, STATIC_RESOLV_CONF, resolved, NULL, MS_BIND, NULL);
+                r = mount_verbose(LOG_WARNING, what, resolved, NULL, MS_BIND, NULL);
                 if (r >= 0)
                         return mount_verbose(LOG_ERR, NULL, resolved, NULL, MS_BIND|MS_REMOUNT|MS_RDONLY|MS_NOSUID|MS_NODEV, NULL);
         }
 
         /* If that didn't work, let's copy the file */
-        r = copy_file("/etc/resolv.conf", where, O_TRUNC|O_NOFOLLOW, 0644, 0, COPY_REFLINK);
+        r = copy_file(what, where, O_TRUNC|O_NOFOLLOW, 0644, 0, COPY_REFLINK);
         if (r < 0) {
                 /* If the file already exists as symlink, let's suppress the warning, under the assumption that
                  * resolved or something similar runs inside and the symlink points there.
                  *
                  * If the disk image is read-only, there's also no point in complaining.
                  */
-                log_full_errno(IN_SET(r, -ELOOP, -EROFS, -EACCES, -EPERM) ? LOG_DEBUG : LOG_WARNING, r,
+                log_full_errno(!IN_SET(RESOLV_CONF_COPY_HOST, RESOLV_CONF_COPY_STATIC) && IN_SET(r, -ELOOP, -EROFS, -EACCES, -EPERM) ? LOG_DEBUG : LOG_WARNING, r,
                                "Failed to copy /etc/resolv.conf to %s, ignoring: %m", where);
                 return 0;
         }
@@ -1470,31 +1731,35 @@ static int setup_resolv_conf(const char *dest) {
 }
 
 static int setup_boot_id(void) {
+        _cleanup_(unlink_and_freep) char *from = NULL;
+        _cleanup_free_ char *path = NULL;
         sd_id128_t rnd = SD_ID128_NULL;
-        const char *from, *to;
+        const char *to;
         int r;
 
         /* Generate a new randomized boot ID, so that each boot-up of
          * the container gets a new one */
 
-        from = "/run/proc-sys-kernel-random-boot-id";
-        to = "/proc/sys/kernel/random/boot_id";
+        r = tempfn_random_child(NULL, "proc-sys-kernel-random-boot-id", &path);
+        if (r < 0)
+                return log_error_errno(r, "Failed to generate random boot ID path: %m");
 
         r = sd_id128_randomize(&rnd);
         if (r < 0)
                 return log_error_errno(r, "Failed to generate random boot id: %m");
 
-        r = id128_write(from, ID128_UUID, rnd, false);
+        r = id128_write(path, ID128_UUID, rnd, false);
         if (r < 0)
                 return log_error_errno(r, "Failed to write boot id: %m");
 
+        from = TAKE_PTR(path);
+        to = "/proc/sys/kernel/random/boot_id";
+
         r = mount_verbose(LOG_ERR, from, to, NULL, MS_BIND, NULL);
-        if (r >= 0)
-                r = mount_verbose(LOG_ERR, NULL, to, NULL,
-                                  MS_BIND|MS_REMOUNT|MS_RDONLY|MS_NOSUID|MS_NODEV, NULL);
+        if (r < 0)
+                return r;
 
-        (void) unlink(from);
-        return r;
+        return mount_verbose(LOG_ERR, NULL, to, NULL, MS_BIND|MS_REMOUNT|MS_RDONLY|MS_NOSUID|MS_NOEXEC|MS_NODEV, NULL);
 }
 
 static int copy_devnodes(const char *dest) {
@@ -1662,26 +1927,32 @@ static int setup_keyring(void) {
 }
 
 static int setup_kmsg(int kmsg_socket) {
-        const char *from, *to;
+        _cleanup_(unlink_and_freep) char *from = NULL;
+        _cleanup_free_ char *fifo = NULL;
+        _cleanup_close_ int fd = -1;
         _cleanup_umask_ mode_t u;
-        int fd, r;
+        const char *to;
+        int r;
 
         assert(kmsg_socket >= 0);
 
         u = umask(0000);
 
-        /* We create the kmsg FIFO as /run/kmsg, but immediately
-         * delete it after bind mounting it to /proc/kmsg. While FIFOs
-         * on the reading side behave very similar to /proc/kmsg,
-         * their writing side behaves differently from /dev/kmsg in
-         * that writing blocks when nothing is reading. In order to
-         * avoid any problems with containers deadlocking due to this
-         * we simply make /dev/kmsg unavailable to the container. */
-        from = "/run/kmsg";
-        to = "/proc/kmsg";
+        /* We create the kmsg FIFO as as temporary file in /tmp, but immediately delete it after bind mounting it to
+         * /proc/kmsg. While FIFOs on the reading side behave very similar to /proc/kmsg, their writing side behaves
+         * differently from /dev/kmsg in that writing blocks when nothing is reading. In order to avoid any problems
+         * with containers deadlocking due to this we simply make /dev/kmsg unavailable to the container. */
+
+        r = tempfn_random_child(NULL, "proc-kmsg", &fifo);
+        if (r < 0)
+                return log_error_errno(r, "Failed to generate kmsg path: %m");
 
-        if (mkfifo(from, 0600) < 0)
+        if (mkfifo(fifo, 0600) < 0)
                 return log_error_errno(errno, "mkfifo() for /run/kmsg failed: %m");
+
+        from = TAKE_PTR(fifo);
+        to = "/proc/kmsg";
+
         r = mount_verbose(LOG_ERR, from, to, NULL, MS_BIND, NULL);
         if (r < 0)
                 return r;
@@ -1690,17 +1961,11 @@ static int setup_kmsg(int kmsg_socket) {
         if (fd < 0)
                 return log_error_errno(errno, "Failed to open fifo: %m");
 
-        /* Store away the fd in the socket, so that it stays open as
-         * long as we run the child */
+        /* Store away the fd in the socket, so that it stays open as long as we run the child */
         r = send_one_fd(kmsg_socket, fd, 0);
-        safe_close(fd);
-
         if (r < 0)
                 return log_error_errno(r, "Failed to send FIFO fd: %m");
 
-        /* And now make the FIFO unavailable as /run/kmsg... */
-        (void) unlink(from);
-
         return 0;
 }
 
@@ -1716,12 +1981,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;
 }
@@ -2265,7 +2532,7 @@ static int inner_child(
 
         _cleanup_free_ char *home = NULL;
         char as_uuid[37];
-        unsigned n_env = 1;
+        size_t n_env = 1;
         const char *envp[] = {
                 "PATH=" DEFAULT_PATH_COMPAT,
                 NULL, /* container */
@@ -2280,7 +2547,6 @@ static int inner_child(
                 NULL
         };
         const char *exec_target;
-
         _cleanup_strv_free_ char **env_use = NULL;
         int r;
 
@@ -2375,11 +2641,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);
@@ -2401,6 +2677,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);
 
@@ -2452,15 +2732,12 @@ static int inner_child(
                         return r;
         }
 
-        /* Now, explicitly close the log, so that we
-         * then can close all remaining fds. Closing
-         * the log explicitly first has the benefit
-         * that the logging subsystem knows about it,
-         * and is thus ready to be reopened should we
-         * need it again. Note that the other fds
-         * closed here are at least the locking and
-         * barrier fds. */
+        /* Now, explicitly close the log, so that we then can close all remaining fds. Closing the log explicitly first
+         * has the benefit that the logging subsystem knows about it, and is thus ready to be reopened should we need
+         * it again. Note that the other fds closed here are at least the locking and barrier fds. */
         log_close();
+        log_set_open_when_needed(true);
+
         (void) fdset_close_others(fds);
 
         if (arg_start_mode == START_BOOT) {
@@ -2498,9 +2775,7 @@ static int inner_child(
                 exec_target = "/bin/bash, /bin/sh";
         }
 
-        r = -errno;
-        (void) log_open();
-        return log_error_errno(r, "execv(%s) failed: %m", exec_target);
+        return log_error_errno(errno, "execv(%s) failed: %m", exec_target);
 }
 
 static int setup_sd_notify_child(void) {
@@ -2557,10 +2832,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);
@@ -2580,6 +2855,11 @@ static int outer_child(
                 if (terminal < 0)
                         return log_error_errno(terminal, "Failed to open console: %m");
 
+                /* Make sure we can continue logging to the original stderr, even if stderr points elsewhere now */
+                r = log_dup_console();
+                if (r < 0)
+                        return log_error_errno(r, "Failed to duplicate stderr: %m");
+
                 r = rearrange_stdio(terminal, terminal, terminal); /* invalidates 'terminal' on success and failure */
                 if (r < 0)
                         return log_error_errno(r, "Failed to move console to stdin/stdout/stderr: %m");
@@ -2803,6 +3083,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));
@@ -3039,86 +3323,19 @@ 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;
-
-        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);
+static int merge_settings(Settings *settings, const char *path) {
+        int rl;
 
-                        /* By default, we trust configuration from /etc and /run */
-                        if (arg_settings_trusted < 0)
-                                arg_settings_trusted = true;
+        assert(settings);
+        assert(path);
 
-                        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) {
                 arg_start_mode = settings->start_mode;
-
-                strv_free(arg_parameters);
-                arg_parameters = TAKE_PTR(settings->parameters);
+                strv_free_and_replace(arg_parameters, settings->parameters);
         }
 
         if ((arg_settings_mask & SETTING_PIVOT_ROOT) == 0 &&
@@ -3132,10 +3349,8 @@ static int load_settings(void) {
                 free_and_replace(arg_chdir, settings->working_directory);
 
         if ((arg_settings_mask & SETTING_ENVIRONMENT) == 0 &&
-            settings->environment) {
-                strv_free(arg_setenv);
-                arg_setenv = TAKE_PTR(settings->environment);
-        }
+            settings->environment)
+                strv_free_and_replace(arg_setenv, settings->environment);
 
         if ((arg_settings_mask & SETTING_USER) == 0 &&
             settings->user)
@@ -3150,7 +3365,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;
 
@@ -3169,7 +3384,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;
         }
@@ -3186,7 +3401,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);
@@ -3206,22 +3421,15 @@ 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);
 
-                        strv_free(arg_network_interfaces);
-                        arg_network_interfaces = TAKE_PTR(settings->network_interfaces);
-
-                        strv_free(arg_network_macvlan);
-                        arg_network_macvlan = TAKE_PTR(settings->network_macvlan);
-
-                        strv_free(arg_network_ipvlan);
-                        arg_network_ipvlan = TAKE_PTR(settings->network_ipvlan);
-
-                        strv_free(arg_network_veth_extra);
-                        arg_network_veth_extra = TAKE_PTR(settings->network_veth_extra);
+                        strv_free_and_replace(arg_network_interfaces, settings->network_interfaces);
+                        strv_free_and_replace(arg_network_macvlan, settings->network_macvlan);
+                        strv_free_and_replace(arg_network_ipvlan, settings->network_ipvlan);
+                        strv_free_and_replace(arg_network_veth_extra, settings->network_veth_extra);
 
                         free_and_replace(arg_network_bridge, settings->network_bridge);
                         free_and_replace(arg_network_zone, settings->network_zone);
@@ -3232,7 +3440,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);
@@ -3243,7 +3451,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;
@@ -3258,19 +3466,156 @@ 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 {
-                        strv_free(arg_syscall_whitelist);
-                        strv_free(arg_syscall_blacklist);
+                        arg_oom_score_adjust = settings->oom_score_adjust;
+                        arg_oom_score_adjust_set = true;
+                }
+        }
+
+        if ((arg_settings_mask & SETTING_CPU_AFFINITY) == 0 &&
+            settings->cpuset) {
 
-                        arg_syscall_whitelist = TAKE_PTR(settings->syscall_whitelist);
-                        arg_syscall_blacklist = TAKE_PTR(settings->syscall_blacklist);
+                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;
                 }
         }
 
+        if ((arg_settings_mask & SETTING_RESOLV_CONF) == 0 &&
+            settings->resolv_conf != _RESOLV_CONF_MODE_INVALID)
+                arg_resolv_conf = settings->resolv_conf;
+
+        if ((arg_settings_mask & SETTING_LINK_JOURNAL) == 0 &&
+            settings->link_journal != _LINK_JOURNAL_INVALID) {
+
+                if (!arg_settings_trusted)
+                        log_warning("Ignoring journal link setting, file '%s' is not trusted.", path);
+                else {
+                        arg_link_journal = settings->link_journal;
+                        arg_link_journal_try = settings->link_journal_try;
+                }
+        }
+
+        if ((arg_settings_mask & SETTING_TIMEZONE) == 0 &&
+            settings->timezone != _TIMEZONE_MODE_INVALID)
+                arg_timezone = settings->timezone;
+
         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,
@@ -3639,11 +3984,9 @@ static int run(int master,
         if (r < 0)
                 return r;
 
-        if (arg_keep_unit) {
-                r = create_subcgroup(*pid, arg_unified_cgroup_hierarchy);
-                if (r < 0)
-                        return r;
-        }
+        r = create_subcgroup(*pid, arg_keep_unit, arg_unified_cgroup_hierarchy);
+        if (r < 0)
+                return r;
 
         r = chown_cgroup(*pid, arg_unified_cgroup_hierarchy, arg_uid_shift);
         if (r < 0)
@@ -3694,20 +4037,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);
@@ -3781,6 +4124,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;
@@ -3813,6 +4221,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;
@@ -3936,17 +4348,30 @@ int main(int argc, char *argv[]) {
                 }
 
                 if (arg_start_mode == START_BOOT) {
-                        if (path_is_os_tree(arg_directory) <= 0) {
-                                log_error("Directory %s doesn't look like an OS root directory (os-release file is missing). Refusing.", arg_directory);
+                        const char *p;
+
+                        if (arg_pivot_root_new)
+                                p = prefix_roota(arg_directory, arg_pivot_root_new);
+                        else
+                                p = arg_directory;
+
+                        if (path_is_os_tree(p) <= 0) {
+                                log_error("Directory %s doesn't look like an OS root directory (os-release file is missing). Refusing.", p);
                                 r = -EINVAL;
                                 goto finish;
                         }
                 } else {
-                        const char *p;
+                        const char *p, *q;
+
+                        if (arg_pivot_root_new)
+                                p = prefix_roota(arg_directory, arg_pivot_root_new);
+                        else
+                                p = arg_directory;
+
+                        q = strjoina(p, "/usr/");
 
-                        p = strjoina(arg_directory, "/usr/");
-                        if (laccess(p, F_OK) < 0) {
-                                log_error("Directory %s doesn't look like it has an OS tree. Refusing.", arg_directory);
+                        if (laccess(q, F_OK) < 0) {
+                                log_error("Directory %s doesn't look like it has an OS tree. Refusing.", p);
                                 r = -EINVAL;
                                 goto finish;
                         }
@@ -4091,7 +4516,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;
         }
@@ -4126,6 +4551,8 @@ finish:
         if (pid > 0)
                 (void) wait_for_terminate(pid, NULL);
 
+        pager_close();
+
         if (remove_directory && arg_directory) {
                 int k;
 
@@ -4161,6 +4588,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);
@@ -4175,6 +4603,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 10c8fb5fb67cb69162a70375218f9d0598e0ad1f..26b3a811ade9c91e99ed9bf419aa0e563c49439d 100644 (file)
@@ -27,6 +27,7 @@
 #include "resolvectl.h"
 #include "resolved-def.h"
 #include "resolved-dns-packet.h"
+#include "string-table.h"
 #include "strv.h"
 #include "terminal-util.h"
 #include "verbs.h"
@@ -40,13 +41,6 @@ static bool arg_legend = true;
 static uint64_t arg_flags = 0;
 static bool arg_no_pager = false;
 bool arg_ifindex_permissive = false; /* If true, don't generate an error if the specified interface index doesn't exist */
-
-typedef enum ServiceFamily {
-        SERVICE_FAMILY_TCP,
-        SERVICE_FAMILY_UDP,
-        SERVICE_FAMILY_SCTP,
-        _SERVICE_FAMILY_INVALID = -1,
-} ServiceFamily;
 static const char *arg_service_family = NULL;
 
 typedef enum RawType {
@@ -89,29 +83,6 @@ static int parse_ifindex_with_warn(const char *s) {
         return ifi;
 }
 
-static ServiceFamily service_family_from_string(const char *s) {
-        if (!s || streq(s, "tcp"))
-                return SERVICE_FAMILY_TCP;
-        if (streq(s, "udp"))
-                return SERVICE_FAMILY_UDP;
-        if (streq(s, "sctp"))
-                return SERVICE_FAMILY_SCTP;
-        return _SERVICE_FAMILY_INVALID;
-}
-
-static const char* service_family_to_string(ServiceFamily service) {
-        switch(service) {
-        case SERVICE_FAMILY_TCP:
-                return "_tcp";
-        case SERVICE_FAMILY_UDP:
-                return "_udp";
-        case SERVICE_FAMILY_SCTP:
-                return "_sctp";
-        default:
-                assert_not_reached("invalid service");
-        }
-}
-
 static void print_source(uint64_t flags, usec_t rtt) {
         char rtt_str[FORMAT_TIMESTAMP_MAX];
 
@@ -941,7 +912,7 @@ static int verb_openpgp(int argc, char **argv, void *userdata) {
         return r;
 }
 
-static int resolve_tlsa(sd_bus *bus, ServiceFamily family, const char *address) {
+static int resolve_tlsa(sd_bus *bus, const char *family, const char *address) {
         const char *port;
         uint16_t port_num = 443;
         _cleanup_free_ char *full = NULL;
@@ -959,9 +930,9 @@ static int resolve_tlsa(sd_bus *bus, ServiceFamily family, const char *address)
                 address = strndupa(address, port - address);
         }
 
-        r = asprintf(&full, "_%u.%s.%s",
+        r = asprintf(&full, "_%u._%s.%s",
                      port_num,
-                     service_family_to_string(family),
+                     family,
                      address);
         if (r < 0)
                 return log_oom();
@@ -973,17 +944,20 @@ static int resolve_tlsa(sd_bus *bus, ServiceFamily family, const char *address)
                               arg_type ?: DNS_TYPE_TLSA, true);
 }
 
+static bool service_family_is_valid(const char *s) {
+        return STR_IN_SET(s, "tcp", "udp", "sctp");
+}
+
 static int verb_tlsa(int argc, char **argv, void *userdata) {
         sd_bus *bus = userdata;
-        ServiceFamily family;
         char **p, **args = argv + 1;
+        const char *family = "tcp";
         int q, r = 0;
 
-        family = service_family_from_string(argv[1]);
-        if (family < 0)
-                family = SERVICE_FAMILY_TCP;
-        else
+        if (service_family_is_valid(argv[1])) {
+                family = argv[1];
                 args++;
+        }
 
         STRV_FOREACH(p, args) {
                 q = resolve_tlsa(bus, family, *p);
@@ -1484,13 +1458,14 @@ static int status_ifindex(sd_bus *bus, int ifindex, const char *name, StatusMode
         printf("       LLMNR setting: %s\n"
                "MulticastDNS setting: %s\n"
                "      DNSSEC setting: %s\n"
-               "    DNSSEC supported: %s\n"
-               "  Current DNS Server: %s\n",
+               "    DNSSEC supported: %s\n",
                strna(link_info.llmnr),
                strna(link_info.mdns),
                strna(link_info.dnssec),
-               yes_no(link_info.dnssec_supported),
-               strna(link_info.current_dns));
+               yes_no(link_info.dnssec_supported));
+
+        if (link_info.current_dns)
+                printf("  Current DNS Server: %s\n", link_info.current_dns);
 
         STRV_FOREACH(i, link_info.dns) {
                 printf("         %s %s\n",
@@ -1622,6 +1597,7 @@ static int status_global(sd_bus *bus, StatusMode mode, bool *empty_line) {
         struct global_info {
                 char *current_dns;
                 char **dns;
+                char **fallback_dns;
                 char **domains;
                 char **ntas;
                 const char *llmnr;
@@ -1632,6 +1608,7 @@ static int status_global(sd_bus *bus, StatusMode mode, bool *empty_line) {
 
         static const struct bus_properties_map property_map[] = {
                 { "DNS",                        "a(iiay)", map_global_dns_servers,        offsetof(struct global_info, dns)              },
+                { "FallbackDNS",                "a(iiay)", map_global_dns_servers,        offsetof(struct global_info, fallback_dns)     },
                 { "CurrentDNSServer",           "(iiay)",  map_global_current_dns_server, offsetof(struct global_info, current_dns)      },
                 { "Domains",                    "a(isb)",  map_global_domains,            offsetof(struct global_info, domains)          },
                 { "DNSSECNegativeTrustAnchors", "as",      NULL,                          offsetof(struct global_info, ntas)             },
@@ -1709,13 +1686,14 @@ static int status_global(sd_bus *bus, StatusMode mode, bool *empty_line) {
         printf("       LLMNR setting: %s\n"
                "MulticastDNS setting: %s\n"
                "      DNSSEC setting: %s\n"
-               "    DNSSEC supported: %s\n"
-               "  Current DNS Server: %s\n",
+               "    DNSSEC supported: %s\n",
                strna(global_info.llmnr),
                strna(global_info.mdns),
                strna(global_info.dnssec),
-               yes_no(global_info.dnssec_supported),
-               strna(global_info.current_dns));
+               yes_no(global_info.dnssec_supported));
+
+        if (global_info.current_dns)
+                printf("  Current DNS Server: %s\n", global_info.current_dns);
 
         STRV_FOREACH(i, global_info.dns) {
                 printf("         %s %s\n",
@@ -1723,6 +1701,12 @@ static int status_global(sd_bus *bus, StatusMode mode, bool *empty_line) {
                        *i);
         }
 
+        STRV_FOREACH(i, global_info.fallback_dns) {
+                printf("%s %s\n",
+                       i == global_info.fallback_dns ? "Fallback DNS Servers:" : "                     ",
+                       *i);
+        }
+
         STRV_FOREACH(i, global_info.domains) {
                 printf("          %s %s\n",
                        i == global_info.domains ? "DNS Domain:" : "           ",
@@ -1743,6 +1727,7 @@ static int status_global(sd_bus *bus, StatusMode mode, bool *empty_line) {
 finish:
         free(global_info.current_dns);
         strv_free(global_info.dns);
+        strv_free(global_info.fallback_dns);
         strv_free(global_info.domains);
         strv_free(global_info.ntas);
 
@@ -2248,29 +2233,17 @@ static void help_protocol_types(void) {
 }
 
 static void help_dns_types(void) {
-        const char *t;
-        int i;
-
         if (arg_legend)
                 puts("Known DNS RR types:");
-        for (i = 0; i < _DNS_TYPE_MAX; i++) {
-                t = dns_type_to_string(i);
-                if (t)
-                        puts(t);
-        }
+
+        DUMP_STRING_TABLE(dns_type, int, _DNS_TYPE_MAX);
 }
 
 static void help_dns_classes(void) {
-        const char *t;
-        int i;
-
         if (arg_legend)
                 puts("Known DNS RR classes:");
-        for (i = 0; i < _DNS_CLASS_MAX; i++) {
-                t = dns_class_to_string(i);
-                if (t)
-                        puts(t);
-        }
+
+        DUMP_STRING_TABLE(dns_class, int, _DNS_CLASS_MAX);
 }
 
 static void compat_help(void) {
@@ -2531,11 +2504,12 @@ static int compat_parse_argv(int argc, char *argv[]) {
 
                 case ARG_TLSA:
                         arg_mode = MODE_RESOLVE_TLSA;
-                        if (service_family_from_string(arg_service_family) < 0) {
+                        if (!optarg || service_family_is_valid(optarg))
+                                arg_service_family = optarg;
+                        else {
                                 log_error("Unknown service family \"%s\".", optarg);
                                 return -EINVAL;
                         }
-                        arg_service_family = optarg;
                         break;
 
                 case ARG_RAW:
index bea0f2a06f1bdec84cc0384950da609efdb6c4e7..b98f862be0990cab6d3f7bdff5f7f43da8ed8ccb 100644 (file)
@@ -1258,7 +1258,6 @@ static int bus_property_get_dns_servers(
                 sd_bus_error *error) {
 
         Manager *m = userdata;
-        unsigned c = 0;
         DnsServer *s;
         Iterator i;
         Link *l;
@@ -1275,8 +1274,6 @@ static int bus_property_get_dns_servers(
                 r = bus_dns_server_append(reply, s, true);
                 if (r < 0)
                         return r;
-
-                c++;
         }
 
         HASHMAP_FOREACH(l, m->links, i) {
@@ -1284,16 +1281,35 @@ static int bus_property_get_dns_servers(
                         r = bus_dns_server_append(reply, s, true);
                         if (r < 0)
                                 return r;
-                        c++;
                 }
         }
 
-        if (c == 0) {
-                LIST_FOREACH(servers, s, m->fallback_dns_servers) {
-                        r = bus_dns_server_append(reply, s, true);
-                        if (r < 0)
-                                return r;
-                }
+        return sd_bus_message_close_container(reply);
+}
+
+static int bus_property_get_fallback_dns_servers(
+                sd_bus *bus,
+                const char *path,
+                const char *interface,
+                const char *property,
+                sd_bus_message *reply,
+                void *userdata,
+                sd_bus_error *error) {
+
+        DnsServer *s, **f = userdata;
+        int r;
+
+        assert(reply);
+        assert(f);
+
+        r = sd_bus_message_open_container(reply, 'a', "(iiay)");
+        if (r < 0)
+                return r;
+
+        LIST_FOREACH(servers, s, *f) {
+                r = bus_dns_server_append(reply, s, true);
+                if (r < 0)
+                        return r;
         }
 
         return sd_bus_message_close_container(reply);
@@ -1422,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,
@@ -1487,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;
@@ -1848,6 +1832,7 @@ static const sd_bus_vtable resolve_vtable[] = {
         SD_BUS_PROPERTY("LLMNR", "s", bus_property_get_resolve_support, offsetof(Manager, llmnr_support), 0),
         SD_BUS_PROPERTY("MulticastDNS", "s", bus_property_get_resolve_support, offsetof(Manager, mdns_support), 0),
         SD_BUS_PROPERTY("DNS", "a(iiay)", bus_property_get_dns_servers, 0, 0),
+        SD_BUS_PROPERTY("FallbackDNS", "a(iiay)", bus_property_get_fallback_dns_servers, offsetof(Manager, fallback_dns_servers), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("CurrentDNSServer", "(iiay)", bus_property_get_current_dns_server, offsetof(Manager, current_dns_server), 0),
         SD_BUS_PROPERTY("Domains", "a(isb)", bus_property_get_domains, 0, 0),
         SD_BUS_PROPERTY("TransactionStatistics", "(tt)", bus_property_get_transaction_statistics, 0, 0),
@@ -1933,7 +1918,7 @@ int manager_connect_bus(Manager *m) {
         if (r < 0)
                 return log_error_errno(r, "Failed to register dnssd enumerator: %m");
 
-        r = sd_bus_request_name_async(m->bus, NULL, "org.freedesktop.resolve1", 0, NULL, NULL);
+        r = bus_request_name_async_may_reload_dbus(m->bus, NULL, "org.freedesktop.resolve1", 0, NULL);
         if (r < 0)
                 return log_error_errno(r, "Failed to request name: %m");
 
index b323f0a8682beb5c6c0a09a7a5b806b52ae9e83b..aa710afa6ca6139439d72f7b7cbfb4d68dceceaa 100644 (file)
@@ -7,6 +7,8 @@
   Copyright 2014 Tom Gundersen <teg@jklm.no>
 ***/
 
+#include "conf-parser.h"
+
 typedef enum DnsStubListenerMode DnsStubListenerMode;
 
 enum DnsStubListenerMode {
@@ -30,15 +32,14 @@ int manager_add_dns_server_by_string(Manager *m, DnsServerType type, const char
 int manager_parse_dns_server_string_and_warn(Manager *m, DnsServerType type, const char *string);
 
 const struct ConfigPerfItem* resolved_gperf_lookup(const char *key, GPERF_LEN_TYPE length);
-
 const struct ConfigPerfItem* resolved_dnssd_gperf_lookup(const char *key, GPERF_LEN_TYPE length);
 
-int config_parse_dns_servers(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_search_domains(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_dns_stub_listener_mode(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
-int config_parse_dnssd_service_name(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
-int config_parse_dnssd_service_type(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_dnssd_txt(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);
+CONFIG_PARSER_PROTOTYPE(config_parse_dns_servers);
+CONFIG_PARSER_PROTOTYPE(config_parse_search_domains);
+CONFIG_PARSER_PROTOTYPE(config_parse_dns_stub_listener_mode);
+CONFIG_PARSER_PROTOTYPE(config_parse_dnssd_service_name);
+CONFIG_PARSER_PROTOTYPE(config_parse_dnssd_service_type);
+CONFIG_PARSER_PROTOTYPE(config_parse_dnssd_txt);
 
 const char* dns_stub_listener_mode_to_string(DnsStubListenerMode p) _const_;
 DnsStubListenerMode dns_stub_listener_mode_from_string(const char *s) _pure_;
index c5714d9e0af36188ec3bbc2ea2221913ab03c7b0..f2201b5d3909f31d0bea4cc307611c956bdfd899 100644 (file)
@@ -80,7 +80,6 @@ typedef enum DnssecNsecResult {
 
 int dnssec_nsec_test(DnsAnswer *answer, DnsResourceKey *key, DnssecNsecResult *result, bool *authenticated, uint32_t *ttl);
 
-
 int dnssec_test_positive_wildcard(DnsAnswer *a, const char *name, const char *source, const char *zone, bool *authenticated);
 
 const char* dnssec_result_to_string(DnssecResult m) _const_;
index 12dc724b60690b8b29724ec7c9b9f97fa947db18..0ada5b012af4376adfc1a96af012003bae758d23 100644 (file)
@@ -7,7 +7,6 @@
   Copyright 2014 Lennart Poettering
 ***/
 
-
 #include "sd-bus.h"
 
 #include "set.h"
index b7f011dbc6bfe07d4ad9524e773a58ce33550fe4..d900d6744a3136e42e9a55374fcc91a3c94f0f41 100644 (file)
@@ -87,7 +87,6 @@ struct DnsResourceKey {
                 ._name = (char*) n,                     \
         })
 
-
 struct DnsTxtItem {
         size_t length;
         LIST_FIELDS(DnsTxtItem, items);
index 395dd2c5f4f80efb8f1d0cca3ea977d08b880026..763789c450f76d308e440e28b7a732c69e176f3a 100644 (file)
@@ -221,7 +221,7 @@ static int dns_scope_emit_one(DnsScope *s, int fd, DnsPacket *p) {
                 if (DNS_PACKET_QDCOUNT(p) > 1)
                         return -EOPNOTSUPP;
 
-                if (!ratelimit_test(&s->ratelimit))
+                if (!ratelimit_below(&s->ratelimit))
                         return -EBUSY;
 
                 family = s->family;
@@ -246,7 +246,7 @@ static int dns_scope_emit_one(DnsScope *s, int fd, DnsPacket *p) {
         case DNS_PROTOCOL_MDNS:
                 assert(fd < 0);
 
-                if (!ratelimit_test(&s->ratelimit))
+                if (!ratelimit_below(&s->ratelimit))
                         return -EBUSY;
 
                 family = s->family;
@@ -759,7 +759,7 @@ void dns_scope_process_query(DnsScope *s, DnsStream *stream, DnsPacket *p) {
         } else {
                 int fd;
 
-                if (!ratelimit_test(&s->ratelimit))
+                if (!ratelimit_below(&s->ratelimit))
                         return;
 
                 if (p->family == AF_INET)
index 57898dbbc1267c13702e0738df8481b97d7b5f7e..51e28796c5b8b6c18d5503a6c326f8dc2ddc1ae8 100644 (file)
@@ -242,18 +242,18 @@ static int dns_trust_anchor_load_positive(DnsTrustAnchor *d, const char *path, u
         }
 
         if (strcaseeq(type, "DS")) {
-                _cleanup_free_ char *key_tag = NULL, *algorithm = NULL, *digest_type = NULL, *digest = NULL;
+                _cleanup_free_ char *key_tag = NULL, *algorithm = NULL, *digest_type = NULL;
                 _cleanup_free_ void *dd = NULL;
                 uint16_t kt;
                 int a, dt;
                 size_t l;
 
-                r = extract_many_words(&p, NULL, 0, &key_tag, &algorithm, &digest_type, &digest, NULL);
+                r = extract_many_words(&p, NULL, 0, &key_tag, &algorithm, &digest_type, NULL);
                 if (r < 0) {
                         log_warning_errno(r, "Failed to parse DS parameters on line %s:%u: %m", path, line);
                         return -EINVAL;
                 }
-                if (r != 4) {
+                if (r != 3) {
                         log_warning("Missing DS parameters on line %s:%u", path, line);
                         return -EINVAL;
                 }
@@ -274,9 +274,14 @@ static int dns_trust_anchor_load_positive(DnsTrustAnchor *d, const char *path, u
                         return -EINVAL;
                 }
 
-                r = unhexmem(digest, strlen(digest), &dd, &l);
+                if (isempty(p)) {
+                        log_warning("Missing DS digest on line %s:%u", path, line);
+                        return -EINVAL;
+                }
+
+                r = unhexmem(p, strlen(p), &dd, &l);
                 if (r < 0) {
-                        log_warning("Failed to parse DS digest %s on line %s:%u", digest, path, line);
+                        log_warning("Failed to parse DS digest %s on line %s:%u", p, path, line);
                         return -EINVAL;
                 }
 
@@ -291,16 +296,16 @@ static int dns_trust_anchor_load_positive(DnsTrustAnchor *d, const char *path, u
                 rr->ds.digest = TAKE_PTR(dd);
 
         } else if (strcaseeq(type, "DNSKEY")) {
-                _cleanup_free_ char *flags = NULL, *protocol = NULL, *algorithm = NULL, *key = NULL;
+                _cleanup_free_ char *flags = NULL, *protocol = NULL, *algorithm = NULL;
                 _cleanup_free_ void *k = NULL;
                 uint16_t f;
                 size_t l;
                 int a;
 
-                r = extract_many_words(&p, NULL, 0, &flags, &protocol, &algorithm, &key, NULL);
+                r = extract_many_words(&p, NULL, 0, &flags, &protocol, &algorithm, NULL);
                 if (r < 0)
                         return log_warning_errno(r, "Failed to parse DNSKEY parameters on line %s:%u: %m", path, line);
-                if (r != 4) {
+                if (r != 3) {
                         log_warning("Missing DNSKEY parameters on line %s:%u", path, line);
                         return -EINVAL;
                 }
@@ -328,9 +333,14 @@ static int dns_trust_anchor_load_positive(DnsTrustAnchor *d, const char *path, u
                         return -EINVAL;
                 }
 
-                r = unbase64mem(key, strlen(key), &k, &l);
+                if (isempty(p)) {
+                        log_warning("Missing DNSKEY key on line %s:%u", path, line);
+                        return -EINVAL;
+                }
+
+                r = unbase64mem(p, strlen(p), &k, &l);
                 if (r < 0)
-                        return log_warning_errno(r, "Failed to parse DNSKEY key data %s on line %s:%u", key, path, line);
+                        return log_warning_errno(r, "Failed to parse DNSKEY key data %s on line %s:%u", p, path, line);
 
                 rr = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_DNSKEY, domain);
                 if (!rr)
@@ -347,11 +357,6 @@ static int dns_trust_anchor_load_positive(DnsTrustAnchor *d, const char *path, u
                 return -EINVAL;
         }
 
-        if (!isempty(p)) {
-                log_warning("Trailing garbage on line %s:%u, ignoring line.", path, line);
-                return -EINVAL;
-        }
-
         r = hashmap_ensure_allocated(&d->positive_by_key, &dns_resource_key_hash_ops);
         if (r < 0)
                 return log_oom();
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 e27b0f4b70218f98ca0dddaf69f9840acc013b37..f54a204c93aa3ba0bea80e32f479c5e57119b34e 100644 (file)
@@ -251,7 +251,7 @@ static int mdns_scope_process_query(DnsScope *s, DnsPacket *p) {
         if (r < 0)
                 return log_debug_errno(r, "Failed to build reply packet: %m");
 
-        if (!ratelimit_test(&s->ratelimit))
+        if (!ratelimit_below(&s->ratelimit))
                 return 0;
 
         r = dns_scope_emit_udp(s, -1, reply);
index 253ac80b87512b854bacf78e8f406abe3e5d0b6f..539a7b4d9da9beabef898a4c472bc07351c7aef1 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 02dea810fbcade2b1690a1393b3d0d17985e7cb8..ed30edfb60f64b5f51873ddaa9cb7240f6563204 100644 (file)
@@ -1078,9 +1078,7 @@ static int map_basic(sd_bus *bus, const char *member, sd_bus_message *m, unsigne
                 if (r < 0)
                         return r;
 
-                strv_free(*p);
-                *p = TAKE_PTR(l);
-                return 0;
+                return strv_free_and_replace(*p, l);
         }
 
         case SD_BUS_TYPE_BOOLEAN: {
@@ -1300,9 +1298,15 @@ int bus_connect_transport(BusTransport transport, const char *host, bool user, s
         case BUS_TRANSPORT_LOCAL:
                 if (user)
                         r = sd_bus_default_user(&bus);
-                else
-                        r = sd_bus_default_system(&bus);
+                else {
+                        if (sd_booted() <= 0) {
+                                /* Print a friendly message when the local system is actually not running systemd as PID 1. */
+                                log_error("System has not been booted with systemd as init system (PID 1). Can't operate.");
 
+                                return -EHOSTDOWN;
+                        }
+                        r = sd_bus_default_system(&bus);
+                }
                 break;
 
         case BUS_TRANSPORT_REMOTE:
@@ -1343,9 +1347,15 @@ int bus_connect_transport_systemd(BusTransport transport, const char *host, bool
         case BUS_TRANSPORT_LOCAL:
                 if (user)
                         r = bus_connect_user_systemd(bus);
-                else
-                        r = bus_connect_system_systemd(bus);
+                else {
+                        if (sd_booted() <= 0) {
+                                /* Print a friendly message when the local system is actually not running systemd as PID 1. */
+                                log_error("System has not been booted with systemd as init system (PID 1). Can't operate.");
 
+                                return -EHOSTDOWN;
+                        }
+                        r = bus_connect_system_systemd(bus);
+                }
                 break;
 
         case BUS_TRANSPORT_REMOTE:
@@ -1603,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);
@@ -1712,3 +1726,124 @@ int bus_open_system_watch_bind_with_description(sd_bus **ret, const char *descri
 
         return 0;
 }
+
+struct request_name_data {
+        const char *name;
+        uint64_t flags;
+        void *userdata;
+};
+
+static int reload_dbus_handler(sd_bus_message *m, void *userdata, sd_bus_error *ret_error) {
+        _cleanup_free_ struct request_name_data *data = userdata;
+        const sd_bus_error *e;
+        int r;
+
+        assert(m);
+        assert(data);
+        assert(data->name);
+
+        e = sd_bus_message_get_error(m);
+        if (e) {
+                log_error_errno(sd_bus_error_get_errno(e), "Failed to reload DBus configuration: %s", e->message);
+                return 1;
+        }
+
+        /* Here, use the default request name handler to avoid an infinite loop of reloading and requesting. */
+        r = sd_bus_request_name_async(sd_bus_message_get_bus(m), NULL, data->name, data->flags, NULL, data->userdata);
+        if (r < 0)
+                log_error_errno(r, "Failed to request name: %m");
+
+        return 1;
+}
+
+static int request_name_handler_may_reload_dbus(sd_bus_message *m, void *userdata, sd_bus_error *ret_error) {
+        _cleanup_free_ struct request_name_data *data = userdata;
+        uint32_t ret;
+        int r;
+
+        assert(m);
+        assert(userdata);
+
+        if (sd_bus_message_is_method_error(m, NULL)) {
+                const sd_bus_error *e = sd_bus_message_get_error(m);
+
+                if (!sd_bus_error_has_name(e, SD_BUS_ERROR_ACCESS_DENIED)) {
+                        log_debug_errno(sd_bus_error_get_errno(e),
+                                        "Unable to request name, failing connection: %s",
+                                        e->message);
+
+                        bus_enter_closing(sd_bus_message_get_bus(m));
+                        return 1;
+                }
+
+                log_debug_errno(sd_bus_error_get_errno(e),
+                                "Unable to request name, retry after reloading DBus configuration: %s",
+                                e->message);
+
+                /* If systemd-timesyncd.service enables DynamicUser= and dbus.service
+                 * started before the dynamic user is realized, then the DBus policy
+                 * about timesyncd has not been enabled yet. So, let's try to reload
+                 * DBus configuration, and after that request name again. Note that it
+                 * seems that no privileges are necessary to call the following method. */
+
+                r = sd_bus_call_method_async(
+                                sd_bus_message_get_bus(m),
+                                NULL,
+                                "org.freedesktop.DBus",
+                                "/org/freedesktop/DBus",
+                                "org.freedesktop.DBus",
+                                "ReloadConfig",
+                                reload_dbus_handler,
+                                userdata, NULL);
+                if (r < 0) {
+                        log_error_errno(r, "Failed to reload DBus configuration: %m");
+                        bus_enter_closing(sd_bus_message_get_bus(m));
+                        return 1;
+                }
+
+                data = NULL; /* Avoid free() */
+                return 1;
+        }
+
+        r = sd_bus_message_read(m, "u", &ret);
+        if (r < 0)
+                return r;
+
+        switch (ret) {
+
+        case BUS_NAME_ALREADY_OWNER:
+                log_debug("Already owner of requested service name, ignoring.");
+                return 1;
+
+        case BUS_NAME_IN_QUEUE:
+                log_debug("In queue for requested service name.");
+                return 1;
+
+        case BUS_NAME_PRIMARY_OWNER:
+                log_debug("Successfully acquired requested service name.");
+                return 1;
+
+        case BUS_NAME_EXISTS:
+                log_debug("Requested service name already owned, failing connection.");
+                bus_enter_closing(sd_bus_message_get_bus(m));
+                return 1;
+        }
+
+        log_debug("Unexpected response from RequestName(), failing connection.");
+        bus_enter_closing(sd_bus_message_get_bus(m));
+        return 1;
+}
+
+int bus_request_name_async_may_reload_dbus(sd_bus *bus, sd_bus_slot **ret_slot, const char *name, uint64_t flags, void *userdata) {
+        struct request_name_data *data;
+
+        data = new0(struct request_name_data, 1);
+        if (!data)
+                return -ENOMEM;
+
+        data->name = name;
+        data->flags = flags;
+        data->userdata = userdata;
+
+        return sd_bus_request_name_async(bus, ret_slot, name, flags, request_name_handler_may_reload_dbus, data);
+}
index d03d0f82d9562a20c238ed27478a74b12376d5a3..16aeca74ddb9fb0363e873eb71364b874ae0a42b 100644 (file)
@@ -122,7 +122,7 @@ assert_cc(sizeof(mode_t) == sizeof(uint32_t));
 int bus_log_parse_error(int r);
 int bus_log_create_error(int r);
 
-#define BUS_DEFINE_PROPERTY_GET_ENUM(function, name, type)              \
+#define BUS_DEFINE_PROPERTY_GET_GLOBAL(function, bus_type, val)         \
         int function(sd_bus *bus,                                       \
                      const char *path,                                  \
                      const char *interface,                             \
@@ -131,23 +131,42 @@ int bus_log_create_error(int r);
                      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));             \
+                return sd_bus_message_append(reply, bus_type, val);     \
+        }
+
+#define BUS_DEFINE_PROPERTY_GET2(function, bus_type, data_type, get1, get2) \
+        int function(sd_bus *bus,                                       \
+                     const char *path,                                  \
+                     const char *interface,                             \
+                     const char *property,                              \
+                     sd_bus_message *reply,                             \
+                     void *userdata,                                    \
+                     sd_bus_error *error) {                             \
                                                                         \
-                r = sd_bus_message_append_basic(reply, 's', value);     \
-                if (r < 0)                                              \
-                        return r;                                       \
+                data_type *data = userdata;                             \
                                                                         \
-                return 1;                                               \
+                assert(bus);                                            \
+                assert(reply);                                          \
+                assert(data);                                           \
+                                                                        \
+                return sd_bus_message_append(reply, bus_type,           \
+                                             get2(get1(data)));         \
         }
 
+#define ident(x) (x)
+#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)              \
+        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)), \
         SD_BUS_PROPERTY(name "Monotonic", "t", bus_property_get_usec, (offset) + offsetof(struct dual_timestamp, monotonic), (flags))
@@ -163,3 +182,5 @@ int bus_open_system_watch_bind_with_description(sd_bus **ret, const char *descri
 static inline int bus_open_system_watch_bind(sd_bus **ret) {
         return bus_open_system_watch_bind_with_description(ret, NULL);
 }
+
+int bus_request_name_async_may_reload_dbus(sd_bus *bus, sd_bus_slot **ret_slot, const char *name, uint64_t flags, void *userdata);
index fec7c62802234427bd6a0ea7879e61516f61b650..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,
@@ -401,6 +402,27 @@ int config_parse(const char *unit,
                 continuation = mfree(continuation);
         }
 
+        if (continuation) {
+                r = parse_line(unit,
+                               filename,
+                               ++line,
+                               sections,
+                               lookup,
+                               table,
+                               flags,
+                               &section,
+                               &section_line,
+                               &section_ignored,
+                               continuation,
+                               userdata);
+                if (r < 0) {
+                        if (flags & CONFIG_PARSE_WARN)
+                                log_warning_errno(r, "%s:%u: Failed to parse file: %m", filename, line);
+                        return r;
+
+                }
+        }
+
         return 0;
 }
 
@@ -686,7 +708,7 @@ int config_parse_string(
                 void *data,
                 void *userdata) {
 
-        char **s = data, *n;
+        char **s = data;
 
         assert(filename);
         assert(lvalue);
@@ -698,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;
 }
@@ -1193,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..0b0532d1abd82c44ddd8c1d39cb5cac7f9b34c02 100644 (file)
@@ -26,17 +26,26 @@ typedef enum ConfigParseFlags {
         CONFIG_PARSE_REFUSE_BOM    = 1U << 3,
 } ConfigParseFlags;
 
+/* Argument list for parsers of specific configuration settings. */
+#define CONFIG_PARSER_ARGUMENTS                 \
+        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
+
 /* Prototype for a parser for a specific configuration setting */
-typedef int (*ConfigParserCallback)(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);
+typedef int (*ConfigParserCallback)(CONFIG_PARSER_ARGUMENTS);
+
+/* A macro declaring the a function prototype, following the typedef above, simply because it's so cumbersomely long
+ * otherwise. (And current emacs gets irritatingly slow when editing files that contain lots of very long function
+ * prototypes on the same screen…) */
+#define CONFIG_PARSER_PROTOTYPE(name) int name(CONFIG_PARSER_ARGUMENTS)
 
 /* Wraps information for parsing a specific configuration variable, to
  * be stored in a simple array */
@@ -107,46 +116,35 @@ int config_parse_many(
                 ConfigParseFlags flags,
                 void *userdata);
 
-/* Generic parsers */
-#define GENERIC_PARSER_ARGS \
-                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_int(GENERIC_PARSER_ARGS);
-int config_parse_unsigned(GENERIC_PARSER_ARGS);
-int config_parse_long(GENERIC_PARSER_ARGS);
-int config_parse_uint8(GENERIC_PARSER_ARGS);
-int config_parse_uint16(GENERIC_PARSER_ARGS);
-int config_parse_uint32(GENERIC_PARSER_ARGS);
-int config_parse_uint64(GENERIC_PARSER_ARGS);
-int config_parse_double(GENERIC_PARSER_ARGS);
-int config_parse_iec_size(GENERIC_PARSER_ARGS);
-int config_parse_si_size(GENERIC_PARSER_ARGS);
-int config_parse_iec_uint64(GENERIC_PARSER_ARGS);
-int config_parse_bool(GENERIC_PARSER_ARGS);
-int config_parse_tristate(GENERIC_PARSER_ARGS);
-int config_parse_string(GENERIC_PARSER_ARGS);
-int config_parse_path(GENERIC_PARSER_ARGS);
-int config_parse_strv(GENERIC_PARSER_ARGS);
-int config_parse_sec(GENERIC_PARSER_ARGS);
-int config_parse_nsec(GENERIC_PARSER_ARGS);
-int config_parse_mode(GENERIC_PARSER_ARGS);
-int config_parse_warn_compat(GENERIC_PARSER_ARGS);
-int config_parse_log_facility(GENERIC_PARSER_ARGS);
-int config_parse_log_level(GENERIC_PARSER_ARGS);
-int config_parse_signal(GENERIC_PARSER_ARGS);
-int config_parse_personality(GENERIC_PARSER_ARGS);
-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);
+CONFIG_PARSER_PROTOTYPE(config_parse_int);
+CONFIG_PARSER_PROTOTYPE(config_parse_unsigned);
+CONFIG_PARSER_PROTOTYPE(config_parse_long);
+CONFIG_PARSER_PROTOTYPE(config_parse_uint8);
+CONFIG_PARSER_PROTOTYPE(config_parse_uint16);
+CONFIG_PARSER_PROTOTYPE(config_parse_uint32);
+CONFIG_PARSER_PROTOTYPE(config_parse_uint64);
+CONFIG_PARSER_PROTOTYPE(config_parse_double);
+CONFIG_PARSER_PROTOTYPE(config_parse_iec_size);
+CONFIG_PARSER_PROTOTYPE(config_parse_si_size);
+CONFIG_PARSER_PROTOTYPE(config_parse_iec_uint64);
+CONFIG_PARSER_PROTOTYPE(config_parse_bool);
+CONFIG_PARSER_PROTOTYPE(config_parse_tristate);
+CONFIG_PARSER_PROTOTYPE(config_parse_string);
+CONFIG_PARSER_PROTOTYPE(config_parse_path);
+CONFIG_PARSER_PROTOTYPE(config_parse_strv);
+CONFIG_PARSER_PROTOTYPE(config_parse_sec);
+CONFIG_PARSER_PROTOTYPE(config_parse_nsec);
+CONFIG_PARSER_PROTOTYPE(config_parse_mode);
+CONFIG_PARSER_PROTOTYPE(config_parse_warn_compat);
+CONFIG_PARSER_PROTOTYPE(config_parse_log_facility);
+CONFIG_PARSER_PROTOTYPE(config_parse_log_level);
+CONFIG_PARSER_PROTOTYPE(config_parse_signal);
+CONFIG_PARSER_PROTOTYPE(config_parse_personality);
+CONFIG_PARSER_PROTOTYPE(config_parse_ifname);
+CONFIG_PARSER_PROTOTYPE(config_parse_ip_port);
+CONFIG_PARSER_PROTOTYPE(config_parse_join_controllers);
+CONFIG_PARSER_PROTOTYPE(config_parse_mtu);
+CONFIG_PARSER_PROTOTYPE(config_parse_rlimit);
 
 typedef enum Disabled {
         DISABLED_CONFIGURATION,
@@ -155,7 +153,7 @@ typedef enum Disabled {
 } Disabled;
 
 #define DEFINE_CONFIG_PARSE_ENUM(function,name,type,msg)                \
-        int function(GENERIC_PARSER_ARGS) {                             \
+        CONFIG_PARSER_PROTOTYPE(function) {                             \
                 type *i = data, x;                                      \
                                                                         \
                 assert(filename);                                       \
@@ -174,7 +172,7 @@ typedef enum Disabled {
         }
 
 #define DEFINE_CONFIG_PARSE_ENUMV(function,name,type,invalid,msg)              \
-        int function(GENERIC_PARSER_ARGS) {                                    \
+        CONFIG_PARSER_PROTOTYPE(function) {                                    \
                 type **enums = data, x, *ys;                                   \
                 _cleanup_free_ type *xs = NULL;                                \
                 const char *word, *state;                                      \
@@ -228,9 +226,6 @@ typedef enum Disabled {
                         *(xs + i) = invalid;                                   \
                 }                                                              \
                                                                                \
-                free(*enums);                                                  \
-                *enums = xs;                                                   \
-                xs = NULL;                                                     \
-                                                                               \
+                free_and_replace(*enums, xs);                                  \
                 return 0;                                                      \
         }
index 70d77c160f6aa82e30bf9f60be8a246422c0d7e8..58e034e83c4ef3bdfb98a9c3b18d7d9fc9d1fd1d 100644 (file)
@@ -33,7 +33,6 @@
 #define GPT_ROOT_ARM_64_VERITY SD_ID128_MAKE(df,33,00,ce,d6,9f,4c,92,97,8c,9b,fb,0f,38,d8,20)
 #define GPT_ROOT_IA64_VERITY   SD_ID128_MAKE(86,ed,10,d5,b6,07,45,bb,89,57,d3,50,f2,3d,05,71)
 
-
 #if defined(__x86_64__)
 #  define GPT_ROOT_NATIVE GPT_ROOT_X86_64
 #  define GPT_ROOT_SECONDARY GPT_ROOT_X86
index 710037d84b403bf89fc30415d5d2b1043faceede..9b19b5d729d9aee1b9842ca928571fb209aba763 100644 (file)
@@ -55,7 +55,6 @@ struct init_request_bsd {
         char   reserved[128];          /* For future expansion.        */
 };
 
-
 /*
  *     Because of legacy interfaces, "runlevel" and "sleeptime"
  *     aren't in a separate struct in the union.
index 550c553117f4838562c007bbf97b023a0dee70bb..424f4ccdbbc1c5bf3b8d8e88d96a5ee882911157 100644 (file)
@@ -2781,7 +2781,8 @@ static int read_presets(UnitFileScope scope, const char *root_dir, Presets *pres
         assert(scope < _UNIT_FILE_SCOPE_MAX);
         assert(presets);
 
-        if (scope == UNIT_FILE_SYSTEM)
+        switch (scope) {
+        case UNIT_FILE_SYSTEM:
                 r = conf_files_list(&files, ".preset", root_dir, 0,
                                     "/etc/systemd/system-preset",
                                     "/run/systemd/system-preset",
@@ -2791,17 +2792,20 @@ static int read_presets(UnitFileScope scope, const char *root_dir, Presets *pres
                                     "/lib/systemd/system-preset",
 #endif
                                     NULL);
-        else if (scope == UNIT_FILE_GLOBAL)
+                break;
+
+        case UNIT_FILE_GLOBAL:
+        case UNIT_FILE_USER:
                 r = conf_files_list(&files, ".preset", root_dir, 0,
                                     "/etc/systemd/user-preset",
                                     "/run/systemd/user-preset",
                                     "/usr/local/lib/systemd/user-preset",
                                     "/usr/lib/systemd/user-preset",
                                     NULL);
-        else {
-                *presets = (Presets){};
+                break;
 
-                return 0;
+        default:
+                assert_not_reached("Invalid unit file scope");
         }
 
         if (r < 0)
index d0cb38650b60e4f8536688204b58f82d151ba935..e3b076122b0e62ca65d045707a704365d2d785cb 100644 (file)
@@ -2,7 +2,7 @@
 #
 # Copyright 2017 Zbigniew Jędrzejewski-Szmek
 
-shared_sources = '''
+shared_sources = files('''
         acl-util.h
         acpi-fpdt.c
         acpi-fpdt.h
@@ -104,25 +104,25 @@ shared_sources = '''
         watchdog.c
         watchdog.h
         wireguard-netlink.h
-'''.split()
+'''.split())
 
 test_tables_h = files('test-tables.h')
 shared_sources += [test_tables_h]
 
 if conf.get('HAVE_ACL') == 1
-        shared_sources += ['acl-util.c']
+        shared_sources += files('acl-util.c')
 endif
 
 if conf.get('ENABLE_UTMP') == 1
-        shared_sources += ['utmp-wtmp.c']
+        shared_sources += files('utmp-wtmp.c')
 endif
 
 if conf.get('HAVE_SECCOMP') == 1
-        shared_sources += ['seccomp-util.c']
+        shared_sources += files('seccomp-util.c')
 endif
 
 if conf.get('HAVE_LIBIPTC') == 1
-        shared_sources += ['firewall-util.c']
+        shared_sources += files('firewall-util.c')
 endif
 
 libshared_name = 'systemd-shared-@0@'.format(meson.project_version())
index 95c40cc91da2e9bb0e59f771f47e00931f99493a..9919b2f2c2869efd72d86701e3385c6fdf39b58d 100644 (file)
@@ -828,14 +828,14 @@ void lookup_paths_flush_generator(LookupPaths *p) {
         /* Flush the generated unit files in full */
 
         if (p->generator)
-                (void) rm_rf(p->generator, REMOVE_ROOT);
+                (void) rm_rf(p->generator, REMOVE_ROOT|REMOVE_PHYSICAL);
         if (p->generator_early)
-                (void) rm_rf(p->generator_early, REMOVE_ROOT);
+                (void) rm_rf(p->generator_early, REMOVE_ROOT|REMOVE_PHYSICAL);
         if (p->generator_late)
-                (void) rm_rf(p->generator_late, REMOVE_ROOT);
+                (void) rm_rf(p->generator_late, REMOVE_ROOT|REMOVE_PHYSICAL);
 
         if (p->temporary_dir)
-                (void) rm_rf(p->temporary_dir, REMOVE_ROOT);
+                (void) rm_rf(p->temporary_dir, REMOVE_ROOT|REMOVE_PHYSICAL);
 }
 
 char **generator_binary_paths(UnitFileScope scope) {
index 260e534d638637bb8a7d6ee928fe6c34190ee5ae..069e32963e105c8e4f54dcd5e8342a10192a4f7f 100644 (file)
@@ -7,6 +7,7 @@
   Copyright 2016 Lennart Poettering
 ***/
 
+#include "conf-parser.h"
 #include "macro.h"
 
 typedef enum ResolveSupport ResolveSupport;
@@ -38,8 +39,8 @@ enum DnssecMode {
         _DNSSEC_MODE_INVALID = -1
 };
 
-int config_parse_resolve_support(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_dnssec_mode(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+CONFIG_PARSER_PROTOTYPE(config_parse_resolve_support);
+CONFIG_PARSER_PROTOTYPE(config_parse_dnssec_mode);
 
 const char* resolve_support_to_string(ResolveSupport p) _const_;
 ResolveSupport resolve_support_from_string(const char *s) _pure_;
index fba58ef367503f6e6d84ac247b5bb231174c0f1c..efc547b6c0313a29773f18a045ffbe85b2771956 100644 (file)
@@ -34,7 +34,7 @@ int parse_sleep_config(const char *verb, char ***_modes, char ***_states, usec_t
                 **suspend_mode = NULL, **suspend_state = NULL,
                 **hibernate_mode = NULL, **hibernate_state = NULL,
                 **hybrid_mode = NULL, **hybrid_state = NULL;
-        char **modes, **states;
+        _cleanup_strv_free_ char **modes, **states; /* always initialized below */
         usec_t delay = 180 * USEC_PER_MINUTE;
 
         const ConfigTableItem items[] = {
@@ -90,16 +90,13 @@ int parse_sleep_config(const char *verb, char ***_modes, char ***_states, usec_t
                 assert_not_reached("what verb");
 
         if ((!modes && STR_IN_SET(verb, "hibernate", "hybrid-sleep")) ||
-            (!states && !streq(verb, "suspend-then-hibernate"))) {
-                strv_free(modes);
-                strv_free(states);
+            (!states && !streq(verb, "suspend-then-hibernate")))
                 return log_oom();
-        }
 
         if (_modes)
-                *_modes = modes;
+                *_modes = TAKE_PTR(modes);
         if (_states)
-                *_states = states;
+                *_states = TAKE_PTR(states);
         if (_delay)
                 *_delay = delay;
 
index 8241183727c775a5a3247ff634c62e8e66386af5..f28b767b8bf3b536d9c35373f12bda51da54e450 100644 (file)
@@ -10,6 +10,8 @@
 #include <stdbool.h>
 #include <inttypes.h>
 
+#include "conf-parser.h"
+
 #define VLANID_MAX 4094
 #define VLANID_INVALID UINT16_MAX
 
@@ -20,5 +22,5 @@ static inline bool vlanid_is_valid(uint16_t id) {
 
 int parse_vlanid(const char *p, uint16_t *ret);
 
-int config_parse_default_port_vlanid(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_vlanid(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);
+CONFIG_PARSER_PROTOTYPE(config_parse_default_port_vlanid);
+CONFIG_PARSER_PROTOTYPE(config_parse_vlanid);
index d70d5856d328069ee0f78c82389d2bd5f9df086d..a20f0b43f45bd68dba1b3f5084364205ea96d794 100644 (file)
 #include "macro.h"
 #include "parse-util.h"
 #include "proc-cmdline.h"
+#include "string-table.h"
 #include "string-util.h"
 #include "volatile-util.h"
 
-VolatileMode volatile_mode_from_string(const char *s) {
-        int b;
-
-        if (isempty(s))
-                return _VOLATILE_MODE_INVALID;
-
-        b = parse_boolean(s);
-        if (b > 0)
-                return VOLATILE_YES;
-        if (b == 0)
-                return VOLATILE_NO;
-
-        if (streq(s, "state"))
-                return VOLATILE_STATE;
-
-        return _VOLATILE_MODE_INVALID;
-}
-
 int query_volatile_mode(VolatileMode *ret) {
         _cleanup_free_ char *mode = NULL;
         VolatileMode m = VOLATILE_NO;
@@ -56,3 +39,11 @@ finish:
         *ret = m;
         return r;
 }
+
+static const char* const volatile_mode_table[_VOLATILE_MODE_MAX] = {
+        [VOLATILE_NO] = "no",
+        [VOLATILE_YES] = "yes",
+        [VOLATILE_STATE] = "state",
+};
+
+DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(volatile_mode, VolatileMode, VOLATILE_YES);
index b275bff1767cc2c22eea1019c74cb024850d2ea6..4312c97a995b20f44936a6b14a7ffd244e6176bf 100644 (file)
@@ -16,5 +16,6 @@ typedef enum VolatileMode {
 } VolatileMode;
 
 VolatileMode volatile_mode_from_string(const char *s);
+const char* volatile_mode_to_string(VolatileMode m);
 
 int query_volatile_mode(VolatileMode *ret);
index 75a3680db07206c9096b917b47b05565575e20a7..5489cb96b7a098bf4b4a84955d8a88e17236f9a6 100644 (file)
 #include "string-util.h"
 #include "strv.h"
 #include "sysctl-util.h"
+#include "terminal-util.h"
 #include "util.h"
 
 static char **arg_prefixes = NULL;
-
-static const char conf_file_dirs[] = CONF_PATHS_NULSTR("sysctl.d");
+static bool arg_cat_config = false;
 
 static int apply_all(OrderedHashmap *sysctl_options) {
         char *property, *value;
@@ -83,7 +83,7 @@ static int parse_file(OrderedHashmap *sysctl_options, const char *path, bool ign
 
         assert(path);
 
-        r = search_and_fopen_nulstr(path, "re", NULL, conf_file_dirs, &f);
+        r = search_and_fopen(path, "re", NULL, (const char**) CONF_PATHS_STRV("sysctl.d"), &f);
         if (r < 0) {
                 if (ignore_enoent && r == -ENOENT)
                         return 0;
@@ -168,6 +168,7 @@ static void help(void) {
                "Applies kernel sysctl settings.\n\n"
                "  -h --help             Show this help\n"
                "     --version          Show package version\n"
+               "     --cat-config       Show configuration files\n"
                "     --prefix=PATH      Only apply rules with the specified prefix\n"
                , program_invocation_short_name);
 }
@@ -176,13 +177,15 @@ static int parse_argv(int argc, char *argv[]) {
 
         enum {
                 ARG_VERSION = 0x100,
-                ARG_PREFIX
+                ARG_CAT_CONFIG,
+                ARG_PREFIX,
         };
 
         static const struct option options[] = {
-                { "help",      no_argument,       NULL, 'h'           },
-                { "version",   no_argument,       NULL, ARG_VERSION   },
-                { "prefix",    required_argument, NULL, ARG_PREFIX    },
+                { "help",       no_argument,       NULL, 'h'            },
+                { "version",    no_argument,       NULL, ARG_VERSION    },
+                { "cat-config", no_argument,       NULL, ARG_CAT_CONFIG },
+                { "prefix",     required_argument, NULL, ARG_PREFIX     },
                 {}
         };
 
@@ -202,6 +205,10 @@ static int parse_argv(int argc, char *argv[]) {
                 case ARG_VERSION:
                         return version();
 
+                case ARG_CAT_CONFIG:
+                        arg_cat_config = true;
+                        break;
+
                 case ARG_PREFIX: {
                         char *p;
 
@@ -231,6 +238,11 @@ static int parse_argv(int argc, char *argv[]) {
                         assert_not_reached("Unhandled option");
                 }
 
+        if (arg_cat_config && argc > optind) {
+                log_error("Positional arguments are not allowed with --cat-config");
+                return -EINVAL;
+        }
+
         return 1;
 }
 
@@ -268,12 +280,17 @@ int main(int argc, char *argv[]) {
                 _cleanup_strv_free_ char **files = NULL;
                 char **f;
 
-                r = conf_files_list_nulstr(&files, ".conf", NULL, 0, conf_file_dirs);
+                r = conf_files_list_strv(&files, ".conf", NULL, 0, (const char**) CONF_PATHS_STRV("sysctl.d"));
                 if (r < 0) {
                         log_error_errno(r, "Failed to enumerate sysctl.d files: %m");
                         goto finish;
                 }
 
+                if (arg_cat_config) {
+                        r = cat_files(NULL, files, 0);
+                        goto finish;
+                }
+
                 STRV_FOREACH(f, files) {
                         k = parse_file(sysctl_options, *f, true);
                         if (k < 0 && r == 0)
index a9461aa3911b911761f818bee4eb3d26fb0f7b17..fcc6c08492894ddcc119f661215a79ed4401366e 100644 (file)
@@ -211,12 +211,6 @@ static int acquire_bus(BusFocus focus, sd_bus **ret) {
 
                 user = arg_scope != UNIT_FILE_SYSTEM;
 
-                if (!user && sd_booted() <= 0) {
-                        /* Print a friendly message when the local system is actually not running systemd as PID 1. */
-                        log_error("System has not been booted with systemd as init system (PID 1). Can't operate.");
-                        return -EHOSTDOWN;
-                }
-
                 if (focus == BUS_MANAGER)
                         r = bus_connect_transport_systemd(arg_transport, arg_host, user, &busses[focus]);
                 else
@@ -5320,23 +5314,6 @@ static int show(int argc, char *argv[], void *userdata) {
         return ret;
 }
 
-static int cat_file(const char *filename, bool newline) {
-        _cleanup_close_ int fd;
-
-        fd = open(filename, O_RDONLY|O_CLOEXEC|O_NOCTTY);
-        if (fd < 0)
-                return -errno;
-
-        printf("%s%s# %s%s\n",
-               newline ? "\n" : "",
-               ansi_highlight_blue(),
-               filename,
-               ansi_normal());
-        fflush(stdout);
-
-        return copy_bytes(fd, STDOUT_FILENO, (uint64_t) -1, 0);
-}
-
 static int cat(int argc, char *argv[], void *userdata) {
         _cleanup_(lookup_paths_free) LookupPaths lp = {};
         _cleanup_strv_free_ char **names = NULL;
@@ -5367,7 +5344,6 @@ static int cat(int argc, char *argv[], void *userdata) {
         STRV_FOREACH(name, names) {
                 _cleanup_free_ char *fragment_path = NULL;
                 _cleanup_strv_free_ char **dropin_paths = NULL;
-                char **path;
 
                 r = unit_find_paths(bus, *name, &lp, &fragment_path, &dropin_paths);
                 if (r < 0)
@@ -5394,17 +5370,9 @@ static int cat(int argc, char *argv[], void *userdata) {
                                 arg_scope == UNIT_FILE_SYSTEM ? "" : " --user",
                                 ansi_normal());
 
-                if (fragment_path) {
-                        r = cat_file(fragment_path, false);
-                        if (r < 0)
-                                return log_warning_errno(r, "Failed to cat %s: %m", fragment_path);
-                }
-
-                STRV_FOREACH(path, dropin_paths) {
-                        r = cat_file(*path, path == dropin_paths);
-                        if (r < 0)
-                                return log_warning_errno(r, "Failed to cat %s: %m", *path);
-                }
+                r = cat_files(fragment_path, dropin_paths, 0);
+                if (r < 0)
+                        return r;
         }
 
         return 0;
@@ -7231,81 +7199,64 @@ static void runlevel_help(void) {
 }
 
 static void help_types(void) {
-        int i;
-
         if (!arg_no_legend)
                 puts("Available unit types:");
-        for (i = 0; i < _UNIT_TYPE_MAX; i++)
-                puts(unit_type_to_string(i));
+
+        DUMP_STRING_TABLE(unit_type, UnitType, _UNIT_TYPE_MAX);
 }
 
 static void help_states(void) {
-        int i;
-
         if (!arg_no_legend)
                 puts("Available unit load states:");
-        for (i = 0; i < _UNIT_LOAD_STATE_MAX; i++)
-                puts(unit_load_state_to_string(i));
+        DUMP_STRING_TABLE(unit_load_state, UnitLoadState, _UNIT_LOAD_STATE_MAX);
 
         if (!arg_no_legend)
                 puts("\nAvailable unit active states:");
-        for (i = 0; i < _UNIT_ACTIVE_STATE_MAX; i++)
-                puts(unit_active_state_to_string(i));
+        DUMP_STRING_TABLE(unit_active_state, UnitActiveState, _UNIT_ACTIVE_STATE_MAX);
 
         if (!arg_no_legend)
                 puts("\nAvailable automount unit substates:");
-        for (i = 0; i < _AUTOMOUNT_STATE_MAX; i++)
-                puts(automount_state_to_string(i));
+        DUMP_STRING_TABLE(automount_state, AutomountState, _AUTOMOUNT_STATE_MAX);
 
         if (!arg_no_legend)
                 puts("\nAvailable device unit substates:");
-        for (i = 0; i < _DEVICE_STATE_MAX; i++)
-                puts(device_state_to_string(i));
+        DUMP_STRING_TABLE(device_state, DeviceState, _DEVICE_STATE_MAX);
 
         if (!arg_no_legend)
                 puts("\nAvailable mount unit substates:");
-        for (i = 0; i < _MOUNT_STATE_MAX; i++)
-                puts(mount_state_to_string(i));
+        DUMP_STRING_TABLE(mount_state, MountState, _MOUNT_STATE_MAX);
 
         if (!arg_no_legend)
                 puts("\nAvailable path unit substates:");
-        for (i = 0; i < _PATH_STATE_MAX; i++)
-                puts(path_state_to_string(i));
+        DUMP_STRING_TABLE(path_state, PathState, _PATH_STATE_MAX);
 
         if (!arg_no_legend)
                 puts("\nAvailable scope unit substates:");
-        for (i = 0; i < _SCOPE_STATE_MAX; i++)
-                puts(scope_state_to_string(i));
+        DUMP_STRING_TABLE(scope_state, ScopeState, _SCOPE_STATE_MAX);
 
         if (!arg_no_legend)
                 puts("\nAvailable service unit substates:");
-        for (i = 0; i < _SERVICE_STATE_MAX; i++)
-                puts(service_state_to_string(i));
+        DUMP_STRING_TABLE(service_state, ServiceState, _SERVICE_STATE_MAX);
 
         if (!arg_no_legend)
                 puts("\nAvailable slice unit substates:");
-        for (i = 0; i < _SLICE_STATE_MAX; i++)
-                puts(slice_state_to_string(i));
+        DUMP_STRING_TABLE(slice_state, SliceState, _SLICE_STATE_MAX);
 
         if (!arg_no_legend)
                 puts("\nAvailable socket unit substates:");
-        for (i = 0; i < _SOCKET_STATE_MAX; i++)
-                puts(socket_state_to_string(i));
+        DUMP_STRING_TABLE(socket_state, SocketState, _SOCKET_STATE_MAX);
 
         if (!arg_no_legend)
                 puts("\nAvailable swap unit substates:");
-        for (i = 0; i < _SWAP_STATE_MAX; i++)
-                puts(swap_state_to_string(i));
+        DUMP_STRING_TABLE(swap_state, SwapState, _SWAP_STATE_MAX);
 
         if (!arg_no_legend)
                 puts("\nAvailable target unit substates:");
-        for (i = 0; i < _TARGET_STATE_MAX; i++)
-                puts(target_state_to_string(i));
+        DUMP_STRING_TABLE(target_state, TargetState, _TARGET_STATE_MAX);
 
         if (!arg_no_legend)
                 puts("\nAvailable timer unit substates:");
-        for (i = 0; i < _TIMER_STATE_MAX; i++)
-                puts(timer_state_to_string(i));
+        DUMP_STRING_TABLE(timer_state, TimerState, _TIMER_STATE_MAX);
 }
 
 static int systemctl_parse_argv(int argc, char *argv[]) {
@@ -7601,6 +7552,11 @@ static int systemctl_parse_argv(int argc, char *argv[]) {
                         break;
 
                 case 's':
+                        if (streq(optarg, "help")) {
+                                DUMP_STRING_TABLE(signal, int, _NSIG);
+                                return 0;
+                        }
+
                         arg_signal = signal_from_string(optarg);
                         if (arg_signal < 0) {
                                 log_error("Failed to parse signal string %s.", optarg);
@@ -7634,6 +7590,11 @@ static int systemctl_parse_argv(int argc, char *argv[]) {
                         break;
 
                 case 'o':
+                        if (streq(optarg, "help")) {
+                                DUMP_STRING_TABLE(output_mode, OutputMode, _OUTPUT_MODE_MAX);
+                                return 0;
+                        }
+
                         arg_output = output_mode_from_string(optarg);
                         if (arg_output < 0) {
                                 log_error("Unknown output '%s'.", optarg);
@@ -7691,6 +7652,10 @@ static int systemctl_parse_argv(int argc, char *argv[]) {
                         break;
 
                 case ARG_PRESET_MODE:
+                        if (streq(optarg, "help")) {
+                                DUMP_STRING_TABLE(unit_file_preset_mode, UnitFilePresetMode, _UNIT_FILE_PRESET_MAX);
+                                return 0;
+                        }
 
                         arg_preset_mode = unit_file_preset_mode_from_string(optarg);
                         if (arg_preset_mode < 0) {
index 789cc50174c59239d0356de020f25abc3257a1ef..fd0a56936292d698a510c6e13f7f35b948c66ede 100644 (file)
@@ -82,6 +82,7 @@ enum {
         SD_DHCP_OPTION_REBINDING_T2_TIME           = 59,
         SD_DHCP_OPTION_VENDOR_CLASS_IDENTIFIER     = 60,
         SD_DHCP_OPTION_CLIENT_IDENTIFIER           = 61,
+        SD_DHCP_OPTION_USER_CLASS                  = 77,
         SD_DHCP_OPTION_FQDN                        = 81,
         SD_DHCP_OPTION_NEW_POSIX_TIMEZONE          = 100,
         SD_DHCP_OPTION_NEW_TZDB_TIMEZONE           = 101,
@@ -154,6 +155,9 @@ int sd_dhcp_client_set_hostname(
 int sd_dhcp_client_set_vendor_class_identifier(
                 sd_dhcp_client *client,
                 const char *vci);
+int sd_dhcp_client_set_user_class(
+                sd_dhcp_client *client,
+                const char* const *user_class);
 int sd_dhcp_client_get_lease(
                 sd_dhcp_client *client,
                 sd_dhcp_lease **ret);
index 14d0cbde04dcca860a63dcd05ba03014e666b031..d4921e955905e6a55e964eef271d0113579b86da 100644 (file)
@@ -43,9 +43,9 @@ typedef int (*sd_resolve_getaddrinfo_handler_t)(sd_resolve_query *q, int ret, co
 typedef int (*sd_resolve_getnameinfo_handler_t)(sd_resolve_query *q, int ret, const char *host, const char *serv, void *userdata);
 
 enum {
-        SD_RESOLVE_GET_HOST = UINT64_C(1),
-        SD_RESOLVE_GET_SERVICE = UINT64_C(2),
-        SD_RESOLVE_GET_BOTH = UINT64_C(3),
+        SD_RESOLVE_GET_HOST    = 1 << 0,
+        SD_RESOLVE_GET_SERVICE = 1 << 1,
+        SD_RESOLVE_GET_BOTH = SD_RESOLVE_GET_HOST | SD_RESOLVE_GET_SERVICE,
 };
 
 int sd_resolve_default(sd_resolve **ret);
index 7c5fafcf8a347be61bebc44d454a5fd37c98a1e1..af041d2f74bb3f5ba6771d0ff5219a16415652fb 100644 (file)
@@ -23,6 +23,7 @@
 #include "specifier.h"
 #include "string-util.h"
 #include "strv.h"
+#include "terminal-util.h"
 #include "uid-range.h"
 #include "user-util.h"
 #include "utf8.h"
@@ -61,11 +62,10 @@ typedef struct Item {
 } Item;
 
 static char *arg_root = NULL;
+static bool arg_cat_config = false;
 static const char *arg_replace = NULL;
 static bool arg_inline = false;
 
-static const char conf_file_dirs[] = CONF_PATHS_NULSTR("sysusers.d");
-
 static OrderedHashmap *users = NULL, *groups = NULL;
 static OrderedHashmap *todo_uids = NULL, *todo_gids = NULL;
 static OrderedHashmap *members = NULL;
@@ -1688,7 +1688,7 @@ static int read_config_file(const char *fn, bool ignore_enoent) {
         if (streq(fn, "-"))
                 f = stdin;
         else {
-                r = search_and_fopen_nulstr(fn, "re", arg_root, conf_file_dirs, &rf);
+                r = search_and_fopen(fn, "re", arg_root, (const char**) CONF_PATHS_STRV("sysusers.d"), &rf);
                 if (r < 0) {
                         if (ignore_enoent && r == -ENOENT)
                                 return 0;
@@ -1744,11 +1744,23 @@ static void free_database(Hashmap *by_name, Hashmap *by_id) {
         hashmap_free(by_id);
 }
 
+static int cat_config(void) {
+        _cleanup_strv_free_ char **files = NULL;
+        int r;
+
+        r = conf_files_list_with_replacement(arg_root, CONF_PATHS_STRV("sysusers.d"), arg_replace, &files, NULL);
+        if (r < 0)
+                return r;
+
+        return cat_files(NULL, files, 0);
+}
+
 static void help(void) {
         printf("%s [OPTIONS...] [CONFIGURATION FILE...]\n\n"
                "Creates system user accounts.\n\n"
                "  -h --help                 Show this help\n"
                "     --version              Show package version\n"
+               "     --cat-config           Show configuration files\n"
                "     --root=PATH            Operate on an alternate filesystem root\n"
                "     --replace=PATH         Treat arguments as replacement for PATH\n"
                "     --inline               Treat arguments as configuration lines\n"
@@ -1759,17 +1771,19 @@ static int parse_argv(int argc, char *argv[]) {
 
         enum {
                 ARG_VERSION = 0x100,
+                ARG_CAT_CONFIG,
                 ARG_ROOT,
                 ARG_REPLACE,
                 ARG_INLINE,
         };
 
         static const struct option options[] = {
-                { "help",    no_argument,       NULL, 'h'         },
-                { "version", no_argument,       NULL, ARG_VERSION },
-                { "root",    required_argument, NULL, ARG_ROOT    },
-                { "replace", required_argument, NULL, ARG_REPLACE },
-                { "inline",  no_argument,       NULL, ARG_INLINE  },
+                { "help",       no_argument,       NULL, 'h'            },
+                { "version",    no_argument,       NULL, ARG_VERSION    },
+                { "cat-config", no_argument,       NULL, ARG_CAT_CONFIG },
+                { "root",       required_argument, NULL, ARG_ROOT       },
+                { "replace",    required_argument, NULL, ARG_REPLACE    },
+                { "inline",     no_argument,       NULL, ARG_INLINE     },
                 {}
         };
 
@@ -1789,6 +1803,10 @@ static int parse_argv(int argc, char *argv[]) {
                 case ARG_VERSION:
                         return version();
 
+                case ARG_CAT_CONFIG:
+                        arg_cat_config = true;
+                        break;
+
                 case ARG_ROOT:
                         r = parse_path_argument_and_warn(optarg, true, &arg_root);
                         if (r < 0)
@@ -1816,6 +1834,11 @@ static int parse_argv(int argc, char *argv[]) {
                         assert_not_reached("Unhandled option");
                 }
 
+        if (arg_replace && arg_cat_config) {
+                log_error("Option --replace= is not supported with --cat-config");
+                return -EINVAL;
+        }
+
         if (arg_replace && optind >= argc) {
                 log_error("When --replace= is given, some configuration items must be specified");
                 return -EINVAL;
@@ -1844,25 +1867,15 @@ static int parse_arguments(char **args) {
         return 0;
 }
 
-static int read_config_files(const char* dirs, char **args) {
+static int read_config_files(char **args) {
         _cleanup_strv_free_ char **files = NULL;
         _cleanup_free_ char *p = NULL;
         char **f;
         int r;
 
-        r = conf_files_list_nulstr(&files, ".conf", arg_root, 0, dirs);
+        r = conf_files_list_with_replacement(arg_root, CONF_PATHS_STRV("sysusers.d"), arg_replace, &files, &p);
         if (r < 0)
-                return log_error_errno(r, "Failed to enumerate sysusers.d files: %m");
-
-        if (arg_replace) {
-                r = conf_files_insert_nulstr(&files, arg_root, dirs, arg_replace);
-                if (r < 0)
-                        return log_error_errno(r, "Failed to extend sysusers.d file list: %m");
-
-                p = path_join(arg_root, arg_replace, NULL);
-                if (!p)
-                        return log_oom();
-        }
+                return r;
 
         STRV_FOREACH(f, files)
                 if (p && path_equal(*f, p)) {
@@ -1882,7 +1895,6 @@ static int read_config_files(const char* dirs, char **args) {
 }
 
 int main(int argc, char *argv[]) {
-
         _cleanup_close_ int lock = -1;
         Iterator iterator;
         int r;
@@ -1897,6 +1909,11 @@ int main(int argc, char *argv[]) {
         log_parse_environment();
         log_open();
 
+        if (arg_cat_config) {
+                r = cat_config();
+                goto finish;
+        }
+
         umask(0022);
 
         r = mac_selinux_init();
@@ -1912,7 +1929,7 @@ int main(int argc, char *argv[]) {
          * read configuration and execute it.
          */
         if (arg_replace || optind >= argc)
-                r = read_config_files(conf_file_dirs, argv + optind);
+                r = read_config_files(argv + optind);
         else
                 r = parse_arguments(argv + optind);
         if (r < 0)
index db62440e9b17db7120cad58b3557f649278fd2c3..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"
@@ -277,6 +278,11 @@ static const char* const config_file[] = {
         "2\\\n"
         "3\n",
 
+        "[Section]\n"
+        "setting1=1\\\n"     /* continuation with extra trailing backslash at the end */
+        "2\\\n"
+        "3\\\n",
+
         "[Section]\n"
         "setting1=1\\\\\\\n" /* continuation with trailing escape symbols */
         "\\\\2\n",           /* note that C requires one level of escaping, so the
@@ -293,6 +299,11 @@ static const char* const config_file[] = {
         x1000("ABCD") "\\\n"
         "foobar",
 
+        "[Section]\n"
+        "setting1="          /* a line above LINE_MAX length, with continuation */
+        x1000("ABCD") "\\\n" /* and an extra trailing backslash */
+        "foobar\\\n",
+
         "[Section]\n"
         "setting1="          /* a line above the allowed limit: 9 + 1050000 + 1 */
         x1000(x1000("x") x10("abcde")) "\n",
@@ -303,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;
@@ -346,27 +357,27 @@ static void test_config_parse(unsigned i, const char *s) {
                 assert_se(streq(setting1, "1"));
                 break;
 
-        case 4:
+        case 4 ... 5:
                 assert_se(r == 0);
                 assert_se(streq(setting1, "1 2 3"));
                 break;
 
-        case 5:
+        case 6:
                 assert_se(r == 0);
                 assert_se(streq(setting1, "1\\\\ \\\\2"));
                 break;
 
-        case 6:
+        case 7:
                 assert_se(r == 0);
                 assert_se(streq(setting1, x1000("ABCD")));
                 break;
 
-        case 7:
+        case 8 ... 9:
                 assert_se(r == 0);
                 assert_se(streq(setting1, x1000("ABCD") " foobar"));
                 break;
 
-        case 8 ... 9:
+        case 10 ... 11:
                 assert_se(r == -ENOBUFS);
                 assert_se(setting1 == NULL);
                 break;
index 9d6a6540c6564743ed06e5325dddad22c43014d5..a02746c76db819a6cef2a48d5091636c51db3e38 100644 (file)
@@ -95,7 +95,7 @@ static void test_copy_tree(void) {
         STRV_FOREACH(p, files) {
                 _cleanup_free_ char *f;
 
-                assert_se((f = strappend(original_dir, *p)));
+                assert_se(f = strappend(original_dir, *p));
 
                 assert_se(mkdir_parents(f, 0755) >= 0);
                 assert_se(write_string_file(f, "file", WRITE_STRING_FILE_CREATE) == 0);
@@ -104,8 +104,8 @@ static void test_copy_tree(void) {
         STRV_FOREACH_PAIR(link, p, links) {
                 _cleanup_free_ char *f, *l;
 
-                assert_se((f = strappend(original_dir, *p)));
-                assert_se((l = strappend(original_dir, *link)));
+                assert_se(f = strappend(original_dir, *p));
+                assert_se(l = strappend(original_dir, *link));
 
                 assert_se(mkdir_parents(l, 0755) >= 0);
                 assert_se(symlink(f, l) == 0);
@@ -117,10 +117,10 @@ static void test_copy_tree(void) {
         assert_se(copy_tree(original_dir, copy_dir, UID_INVALID, GID_INVALID, COPY_REFLINK|COPY_MERGE) == 0);
 
         STRV_FOREACH(p, files) {
-                _cleanup_free_ char *buf = NULL, *f;
-                size_t sz = 0;
+                _cleanup_free_ char *buf, *f;
+                size_t sz;
 
-                assert_se((f = strappend(copy_dir, *p)));
+                assert_se(f = strappend(copy_dir, *p));
 
                 assert_se(access(f, F_OK) == 0);
                 assert_se(read_full_file(f, &buf, &sz) == 0);
@@ -128,10 +128,10 @@ static void test_copy_tree(void) {
         }
 
         STRV_FOREACH_PAIR(link, p, links) {
-                _cleanup_free_ char *target = NULL, *f, *l;
+                _cleanup_free_ char *target, *f, *l;
 
-                assert_se((f = strjoin(original_dir, *p)));
-                assert_se((l = strjoin(copy_dir, *link)));
+                assert_se(f = strjoin(original_dir, *p));
+                assert_se(l = strjoin(copy_dir, *link));
 
                 assert_se(chase_symlinks(l, NULL, 0, &target) == 1);
                 assert_se(path_equal(f, target));
index 151d2d72b214f207273e42979d9f2ae02479b311..febfc60e00ed0783b8f38c84ce2e5f2243866ae2 100644 (file)
@@ -13,7 +13,7 @@
 int main(int argc, char **argv) {
         void *handle;
 
-        assert_se((handle = dlopen(argv[1], RTLD_NOW)));
+        assert_se(handle = dlopen(argv[1], RTLD_NOW));
         assert_se(dlclose(handle) == 0);
 
         return EXIT_SUCCESS;
index 4c33748fc40181ecbf2d5a35c820ed0bc9fb9d88..7095dd2a2efdce5d7ceb9ad9baad171fb732e20c 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"
@@ -434,8 +435,14 @@ static void test_exec_dynamicuser(Manager *m) {
         test(m, "exec-dynamicuser-supplementarygroups.service", 0, CLD_EXITED);
         test(m, "exec-dynamicuser-statedir.service", 0, CLD_EXITED);
 
+        (void) rm_rf("/var/lib/test-dynamicuser-migrate", REMOVE_ROOT|REMOVE_PHYSICAL);
+        (void) rm_rf("/var/lib/test-dynamicuser-migrate2", REMOVE_ROOT|REMOVE_PHYSICAL);
+        (void) rm_rf("/var/lib/private/test-dynamicuser-migrate", REMOVE_ROOT|REMOVE_PHYSICAL);
+        (void) rm_rf("/var/lib/private/test-dynamicuser-migrate2", REMOVE_ROOT|REMOVE_PHYSICAL);
+
         test(m, "exec-dynamicuser-statedir-migrate-step1.service", 0, CLD_EXITED);
         test(m, "exec-dynamicuser-statedir-migrate-step2.service", 0, CLD_EXITED);
+
         (void) rm_rf("/var/lib/test-dynamicuser-migrate", REMOVE_ROOT|REMOVE_PHYSICAL);
         (void) rm_rf("/var/lib/test-dynamicuser-migrate2", REMOVE_ROOT|REMOVE_PHYSICAL);
         (void) rm_rf("/var/lib/private/test-dynamicuser-migrate", REMOVE_ROOT|REMOVE_PHYSICAL);
@@ -458,7 +465,8 @@ static void test_exec_environmentfile(Manager *m) {
                 " ; # comment3\n"
                 "line without an equal\n"
                 "VAR3='$word 5 6'\n"
-                "VAR4='new\nline'\n";
+                "VAR4='new\nline'\n"
+                "VAR5=password\\with\\backslashes";
         int r;
 
         r = write_string_file("/tmp/test-exec_environmentfile.conf", e, WRITE_STRING_FILE_CREATE);
@@ -485,6 +493,7 @@ static void test_exec_passenvironment(Manager *m) {
         assert_se(setenv("VAR2", "word3", 1) == 0);
         assert_se(setenv("VAR3", "$word 5 6", 1) == 0);
         assert_se(setenv("VAR4", "new\nline", 1) == 0);
+        assert_se(setenv("VAR5", "passwordwithbackslashes", 1) == 0);
         test(m, "exec-passenvironment.service", 0, CLD_EXITED);
         test(m, "exec-passenvironment-repeated.service", 0, CLD_EXITED);
         test(m, "exec-passenvironment-empty.service", 0, CLD_EXITED);
@@ -492,6 +501,7 @@ static void test_exec_passenvironment(Manager *m) {
         assert_se(unsetenv("VAR2") == 0);
         assert_se(unsetenv("VAR3") == 0);
         assert_se(unsetenv("VAR4") == 0);
+        assert_se(unsetenv("VAR5") == 0);
         test(m, "exec-passenvironment-absent.service", 0, CLD_EXITED);
 }
 
index ba22e865fd774c20f5bf360efd50cac6880a78a5..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) {
@@ -467,7 +454,7 @@ static void test_write_string_file_verify(void) {
         int r;
 
         assert_se(read_one_line_file("/proc/cmdline", &buf) >= 0);
-        assert_se((buf2 = strjoin(buf, "\n")));
+        assert_se(buf2 = strjoin(buf, "\n"));
 
         r = write_string_file("/proc/cmdline", buf, 0);
         assert_se(IN_SET(r, -EACCES, -EIO));
@@ -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 9a22fc905371f2a9e0eb978611a949002f75cc79..50fcb364faf6cf9df3a379880cca1405bf4b11da 100644 (file)
@@ -125,7 +125,7 @@ static void test_iterated_cache(void) {
 }
 
 static void test_path_hashmap(void) {
-        _cleanup_(hashmap_freep) Hashmap *h = NULL;
+        _cleanup_hashmap_free_ Hashmap *h = NULL;
 
         assert_se(h = hashmap_new(&path_hash_ops));
 
index 18c9fb508d1d82ae837b6b1ecbea8b1f7a7cb4ad..41ca9805fed19f62a1a8367dd558d9b244ecdd62 100644 (file)
@@ -76,20 +76,40 @@ static void test_undecchar(void) {
         assert_se(undecchar('9') == 9);
 }
 
-static void test_unhexmem(void) {
-        const char *hex = "efa2149213";
-        const char *hex_invalid = "efa214921o";
-        _cleanup_free_ char *hex2 = NULL;
+static void test_unhexmem_one(const char *s, size_t l, int retval) {
+        _cleanup_free_ char *hex = NULL;
         _cleanup_free_ void *mem = NULL;
         size_t len;
 
-        assert_se(unhexmem(hex_invalid, strlen(hex_invalid), &mem, &len) == -EINVAL);
-        assert_se(unhexmem(hex, strlen(hex) + 1, &mem, &len) == -EINVAL);
-        assert_se(unhexmem(hex, strlen(hex) - 1, &mem, &len) == -EINVAL);
-        assert_se(unhexmem(hex, strlen(hex), &mem, &len) == 0);
+        assert_se(unhexmem(s, l, &mem, &len) == retval);
+        if (retval == 0) {
+                char *answer;
+
+                if (l == (size_t) -1)
+                        l = strlen(s);
+
+                assert_se(hex = hexmem(mem, len));
+                answer = strndupa(s, l);
+                assert_se(streq(delete_chars(answer, WHITESPACE), hex));
+        }
+}
+
+static void test_unhexmem(void) {
+        const char *hex = "efa2149213";
+        const char *hex_space = "  e f   a\n 2\r  14\n\r\t9\t2 \n1\r3 \r\r\t";
+        const char *hex_invalid = "efa214921o";
 
-        assert_se((hex2 = hexmem(mem, len)));
-        assert_se(streq(hex, hex2));
+        test_unhexmem_one(NULL, 0, 0);
+        test_unhexmem_one("", 0, 0);
+        test_unhexmem_one("", (size_t) -1, 0);
+        test_unhexmem_one("   \n \t\r   \t\t \n\n\n", (size_t) -1, 0);
+        test_unhexmem_one(hex_invalid, strlen(hex_invalid), -EINVAL);
+        test_unhexmem_one(hex_invalid, (size_t) - 1, -EINVAL);
+        test_unhexmem_one(hex, strlen(hex) - 1, -EPIPE);
+        test_unhexmem_one(hex, strlen(hex), 0);
+        test_unhexmem_one(hex, (size_t) -1, 0);
+        test_unhexmem_one(hex_space, strlen(hex_space), 0);
+        test_unhexmem_one(hex_space, (size_t) -1, 0);
 }
 
 /* https://tools.ietf.org/html/rfc4648#section-10 */
@@ -167,94 +187,65 @@ static void test_base32hexmem(void) {
         free(b32);
 }
 
-static void test_unbase32hexmem(void) {
-        void *mem;
+static void test_unbase32hexmem_one(const char *hex, bool padding, int retval, const char *ans) {
+        _cleanup_free_ void *mem = NULL;
         size_t len;
 
-        assert_se(unbase32hexmem("", STRLEN(""), true, &mem, &len) == 0);
-        assert_se(streq(strndupa(mem, len), ""));
-        free(mem);
-
-        assert_se(unbase32hexmem("CO======", STRLEN("CO======"), true, &mem, &len) == 0);
-        assert_se(streq(strndupa(mem, len), "f"));
-        free(mem);
-
-        assert_se(unbase32hexmem("CPNG====", STRLEN("CPNG===="), true, &mem, &len) == 0);
-        assert_se(streq(strndupa(mem, len), "fo"));
-        free(mem);
-
-        assert_se(unbase32hexmem("CPNMU===", STRLEN("CPNMU==="), true, &mem, &len) == 0);
-        assert_se(streq(strndupa(mem, len), "foo"));
-        free(mem);
-
-        assert_se(unbase32hexmem("CPNMUOG=", STRLEN("CPNMUOG="), true, &mem, &len) == 0);
-        assert_se(streq(strndupa(mem, len), "foob"));
-        free(mem);
-
-        assert_se(unbase32hexmem("CPNMUOJ1", STRLEN("CPNMUOJ1"), true, &mem, &len) == 0);
-        assert_se(streq(strndupa(mem, len), "fooba"));
-        free(mem);
-
-        assert_se(unbase32hexmem("CPNMUOJ1E8======", STRLEN("CPNMUOJ1E8======"), true, &mem, &len) == 0);
-        assert_se(streq(strndupa(mem, len), "foobar"));
-        free(mem);
-
-        assert_se(unbase32hexmem("A", STRLEN("A"), true, &mem, &len) == -EINVAL);
-        assert_se(unbase32hexmem("A=======", STRLEN("A======="), true, &mem, &len) == -EINVAL);
-        assert_se(unbase32hexmem("AAA=====", STRLEN("AAA====="), true, &mem, &len) == -EINVAL);
-        assert_se(unbase32hexmem("AAAAAA==", STRLEN("AAAAAA=="), true, &mem, &len) == -EINVAL);
-        assert_se(unbase32hexmem("AB======", STRLEN("AB======"), true, &mem, &len) == -EINVAL);
-        assert_se(unbase32hexmem("AAAB====", STRLEN("AAAB===="), true, &mem, &len) == -EINVAL);
-        assert_se(unbase32hexmem("AAAAB===", STRLEN("AAAAB==="), true, &mem, &len) == -EINVAL);
-        assert_se(unbase32hexmem("AAAAAAB=", STRLEN("AAAAAAB="), true, &mem, &len) == -EINVAL);
-
-        assert_se(unbase32hexmem("XPNMUOJ1", STRLEN("CPNMUOJ1"), true, &mem, &len) == -EINVAL);
-        assert_se(unbase32hexmem("CXNMUOJ1", STRLEN("CPNMUOJ1"), true, &mem, &len) == -EINVAL);
-        assert_se(unbase32hexmem("CPXMUOJ1", STRLEN("CPNMUOJ1"), true, &mem, &len) == -EINVAL);
-        assert_se(unbase32hexmem("CPNXUOJ1", STRLEN("CPNMUOJ1"), true, &mem, &len) == -EINVAL);
-        assert_se(unbase32hexmem("CPNMXOJ1", STRLEN("CPNMUOJ1"), true, &mem, &len) == -EINVAL);
-        assert_se(unbase32hexmem("CPNMUXJ1", STRLEN("CPNMUOJ1"), true, &mem, &len) == -EINVAL);
-        assert_se(unbase32hexmem("CPNMUOX1", STRLEN("CPNMUOJ1"), true, &mem, &len) == -EINVAL);
-        assert_se(unbase32hexmem("CPNMUOJX", STRLEN("CPNMUOJ1"), true, &mem, &len) == -EINVAL);
-
-        assert_se(unbase32hexmem("", STRLEN(""), false, &mem, &len) == 0);
-        assert_se(streq(strndupa(mem, len), ""));
-        free(mem);
-
-        assert_se(unbase32hexmem("CO", STRLEN("CO"), false, &mem, &len) == 0);
-        assert_se(streq(strndupa(mem, len), "f"));
-        free(mem);
-
-        assert_se(unbase32hexmem("CPNG", STRLEN("CPNG"), false, &mem, &len) == 0);
-        assert_se(streq(strndupa(mem, len), "fo"));
-        free(mem);
-
-        assert_se(unbase32hexmem("CPNMU", STRLEN("CPNMU"), false, &mem, &len) == 0);
-        assert_se(streq(strndupa(mem, len), "foo"));
-        free(mem);
-
-        assert_se(unbase32hexmem("CPNMUOG", STRLEN("CPNMUOG"), false, &mem, &len) == 0);
-        assert_se(streq(strndupa(mem, len), "foob"));
-        free(mem);
-
-        assert_se(unbase32hexmem("CPNMUOJ1", STRLEN("CPNMUOJ1"), false, &mem, &len) == 0);
-        assert_se(streq(strndupa(mem, len), "fooba"));
-        free(mem);
-
-        assert_se(unbase32hexmem("CPNMUOJ1E8", STRLEN("CPNMUOJ1E8"), false, &mem, &len) == 0);
-        assert_se(streq(strndupa(mem, len), "foobar"));
-        free(mem);
-
-        assert_se(unbase32hexmem("CPNMUOG=", STRLEN("CPNMUOG="), false, &mem, &len) == -EINVAL);
-        assert_se(unbase32hexmem("CPNMUOJ1E8======", STRLEN("CPNMUOJ1E8======"), false, &mem, &len) == -EINVAL);
-        assert_se(unbase32hexmem("A", STRLEN("A"), false, &mem, &len) == -EINVAL);
-        assert_se(unbase32hexmem("A", STRLEN("A"), false, &mem, &len) == -EINVAL);
-        assert_se(unbase32hexmem("AAA", STRLEN("AAA"), false, &mem, &len) == -EINVAL);
-        assert_se(unbase32hexmem("AAAAAA", STRLEN("AAAAAA"), false, &mem, &len) == -EINVAL);
-        assert_se(unbase32hexmem("AB", STRLEN("AB"), false, &mem, &len) == -EINVAL);
-        assert_se(unbase32hexmem("AAAB", STRLEN("AAAB"), false, &mem, &len) == -EINVAL);
-        assert_se(unbase32hexmem("AAAAB", STRLEN("AAAAB"), false, &mem, &len) == -EINVAL);
-        assert_se(unbase32hexmem("AAAAAAB", STRLEN("AAAAAAB"), false, &mem, &len) == -EINVAL);
+        assert_se(unbase32hexmem(hex, (size_t) -1, padding, &mem, &len) == retval);
+        if (retval == 0) {
+                char *str;
+
+                str = strndupa(mem, len);
+                assert_se(streq(str, ans));
+        }
+}
+
+static void test_unbase32hexmem(void) {
+        test_unbase32hexmem_one("", true, 0, "");
+
+        test_unbase32hexmem_one("CO======", true, 0, "f");
+        test_unbase32hexmem_one("CPNG====", true, 0, "fo");
+        test_unbase32hexmem_one("CPNMU===", true, 0, "foo");
+        test_unbase32hexmem_one("CPNMUOG=", true, 0, "foob");
+        test_unbase32hexmem_one("CPNMUOJ1", true, 0, "fooba");
+        test_unbase32hexmem_one("CPNMUOJ1E8======", true, 0, "foobar");
+
+        test_unbase32hexmem_one("A", true, -EINVAL, NULL);
+        test_unbase32hexmem_one("A=======", true, -EINVAL, NULL);
+        test_unbase32hexmem_one("AAA=====", true, -EINVAL, NULL);
+        test_unbase32hexmem_one("AAAAAA==", true, -EINVAL, NULL);
+        test_unbase32hexmem_one("AB======", true, -EINVAL, NULL);
+        test_unbase32hexmem_one("AAAB====", true, -EINVAL, NULL);
+        test_unbase32hexmem_one("AAAAB===", true, -EINVAL, NULL);
+        test_unbase32hexmem_one("AAAAAAB=", true, -EINVAL, NULL);
+
+        test_unbase32hexmem_one("XPNMUOJ1", true, -EINVAL, NULL);
+        test_unbase32hexmem_one("CXNMUOJ1", true, -EINVAL, NULL);
+        test_unbase32hexmem_one("CPXMUOJ1", true, -EINVAL, NULL);
+        test_unbase32hexmem_one("CPNXUOJ1", true, -EINVAL, NULL);
+        test_unbase32hexmem_one("CPNMXOJ1", true, -EINVAL, NULL);
+        test_unbase32hexmem_one("CPNMUXJ1", true, -EINVAL, NULL);
+        test_unbase32hexmem_one("CPNMUOX1", true, -EINVAL, NULL);
+        test_unbase32hexmem_one("CPNMUOJX", true, -EINVAL, NULL);
+
+        test_unbase32hexmem_one("", false, 0, "");
+        test_unbase32hexmem_one("CO", false, 0, "f");
+        test_unbase32hexmem_one("CPNG", false, 0, "fo");
+        test_unbase32hexmem_one("CPNMU", false, 0, "foo");
+        test_unbase32hexmem_one("CPNMUOG", false, 0, "foob");
+        test_unbase32hexmem_one("CPNMUOJ1", false, 0, "fooba");
+        test_unbase32hexmem_one("CPNMUOJ1E8", false, 0, "foobar");
+        test_unbase32hexmem_one("CPNMUOG=", false, -EINVAL, NULL);
+        test_unbase32hexmem_one("CPNMUOJ1E8======", false, -EINVAL, NULL);
+
+        test_unbase32hexmem_one("A", false, -EINVAL, NULL);
+        test_unbase32hexmem_one("A", false, -EINVAL, NULL);
+        test_unbase32hexmem_one("AAA", false, -EINVAL, NULL);
+        test_unbase32hexmem_one("AAAAAA", false, -EINVAL, NULL);
+        test_unbase32hexmem_one("AB", false, -EINVAL, NULL);
+        test_unbase32hexmem_one("AAAB", false, -EINVAL, NULL);
+        test_unbase32hexmem_one("AAAAB", false, -EINVAL, NULL);
+        test_unbase32hexmem_one("AAAAAAB", false, -EINVAL, NULL);
 }
 
 /* https://tools.ietf.org/html/rfc4648#section-10 */
index f6dee45ac07fb984bae6773b901f4da6403ebc49..6d4c51d6d8abfc5a7c783922be969d4721778798 100644 (file)
@@ -87,7 +87,7 @@ static int print_gaih_addrtuples(const struct gaih_addrtuple *tuples) {
                 r = in_addr_to_string(it->family, &u, &a);
                 assert_se(IN_SET(r, 0, -EAFNOSUPPORT));
                 if (r == -EAFNOSUPPORT)
-                        assert_se((a = hexmem(it->addr, 16)));
+                        assert_se(a = hexmem(it->addr, 16));
 
                 if (it->scopeid == 0)
                         goto numerical_index;
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 3871452232282bb444b0d9b57b012162066c26be..7001e821785ce7bbca281a4870f5efc9269ff5b3 100644 (file)
 #include "ratelimit.h"
 #include "time-util.h"
 
-static void test_ratelimit_test(void) {
+static void test_ratelimit_below(void) {
         int i;
         RATELIMIT_DEFINE(ratelimit, 1 * USEC_PER_SEC, 10);
 
         for (i = 0; i < 10; i++)
-                assert_se(ratelimit_test(&ratelimit));
-        assert_se(!ratelimit_test(&ratelimit));
+                assert_se(ratelimit_below(&ratelimit));
+        assert_se(!ratelimit_below(&ratelimit));
         sleep(1);
         for (i = 0; i < 10; i++)
-                assert_se(ratelimit_test(&ratelimit));
+                assert_se(ratelimit_below(&ratelimit));
 
         RATELIMIT_INIT(ratelimit, 0, 10);
         for (i = 0; i < 10000; i++)
-                assert_se(ratelimit_test(&ratelimit));
+                assert_se(ratelimit_below(&ratelimit));
 }
 
 int main(int argc, char *argv[]) {
-        test_ratelimit_test();
+        test_ratelimit_below();
 
         return 0;
 }
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 2ebbbb304a5cbe02f89fdbe9e4ec6bb6b9b5b426..d7897ed7659d96349929bcfc93aa41c09cedda90 100644 (file)
@@ -26,7 +26,12 @@ enum Enum {
 };
 
 enum BigEnum {
-        big_enum_value = UINT64_C(-1),
+        big_enum_value = UINT64_C(1),
+};
+
+enum BigEnum2 {
+        big_enum2_pos = UINT64_C(1),
+        big_enum2_neg = UINT64_C(-1),
 };
 
 int main(void) {
@@ -55,6 +60,10 @@ int main(void) {
 
         info(enum Enum);
         info(enum BigEnum);
+        info(enum BigEnum2);
+        assert_cc(sizeof(enum BigEnum2) == 8);
+        printf("big_enum2_pos → %zu\n", sizeof(big_enum2_pos));
+        printf("big_enum2_neg → %zu\n", sizeof(big_enum2_neg));
 
         return 0;
 }
index c2cb4ef9494bc39a31a57139dff14b62b4ed313d..1c5b56f4a04f12540eeff9753bc4e98c28b6925c 100644 (file)
 #include "strv.h"
 #include "util.h"
 
+static void test_parse_sleep_config(void) {
+        const char *verb;
+
+        FOREACH_STRING(verb, "suspend", "hibernate", "hybrid-sleep", "suspend-then-hibernate")
+                assert_se(parse_sleep_config(verb, NULL, NULL, NULL) == 0);
+}
+
 static int test_fiemap(const char *path) {
         _cleanup_free_ struct fiemap *fiemap = NULL;
         _cleanup_close_ int fd = -1;
@@ -84,6 +91,7 @@ int main(int argc, char* argv[]) {
         if (getuid() != 0)
                 log_warning("This program is unlikely to work for unprivileged users");
 
+        test_parse_sleep_config();
         test_sleep();
 
         if (argc <= 1)
index 7fe9d662232084592ec8188b0441d55121eacdd5..8e5b8b1d776ac2dbc43c1d268aa2fc16637cb9c0 100644 (file)
@@ -18,7 +18,7 @@ static ssize_t add_string(struct strbuf *sb, const char *s) {
 }
 
 static void test_strbuf(void) {
-        struct strbuf *sb;
+        _cleanup_(strbuf_cleanupp) struct strbuf *sb;
         _cleanup_strv_free_ char **l;
         ssize_t a, b, c, d, e, f, g, h;
 
@@ -72,8 +72,6 @@ static void test_strbuf(void) {
 
         strbuf_complete(sb);
         assert_se(sb->root == NULL);
-
-        strbuf_cleanup(sb);
 }
 
 int main(int argc, const char *argv[]) {
index c83dfa9dcd54e637dc45d8ebb781fd0849b3a6ca..216c8bef0029aa2762bee53fc9d42a02a657baf4 100644 (file)
@@ -14,6 +14,7 @@
 #include "fileio.h"
 #include "log.h"
 #include "macro.h"
+#include "strv.h"
 #include "terminal-util.h"
 #include "util.h"
 
@@ -76,6 +77,14 @@ static void test_terminal_urlify(void) {
         printf("Or click on %s to have a look at it!\n", formatted);
 }
 
+static void test_cat_files(void) {
+        assert_se(cat_files("/no/such/file", NULL, 0) == -ENOENT);
+        assert_se(cat_files("/no/such/file", NULL, CAT_FLAGS_MAIN_FILE_OPTIONAL) == 0);
+
+        if (access("/etc/fstab", R_OK) >= 0)
+                assert_se(cat_files("/etc/fstab", STRV_MAKE("/etc/fstab", "/etc/fstab"), 0) == 0);
+}
+
 int main(int argc, char *argv[]) {
         log_parse_environment();
         log_open();
@@ -83,6 +92,9 @@ int main(int argc, char *argv[]) {
         test_default_term_for_tty();
         test_read_one_char();
         test_terminal_urlify();
+        test_cat_files();
+
+        print_separator();
 
         return 0;
 }
index 5393deff702f56c691cf0405283c5c4dc3d97765..5b8e7c7b35d74572d878af77cc4dd865048a723d 100644 (file)
@@ -168,9 +168,9 @@ static void test_format_timespan(usec_t accuracy) {
 }
 
 static void test_timezone_is_valid(void) {
-        assert_se(timezone_is_valid("Europe/Berlin"));
-        assert_se(timezone_is_valid("Australia/Sydney"));
-        assert_se(!timezone_is_valid("Europe/Do not exist"));
+        assert_se(timezone_is_valid("Europe/Berlin", LOG_ERR));
+        assert_se(timezone_is_valid("Australia/Sydney", LOG_ERR));
+        assert_se(!timezone_is_valid("Europe/Do not exist", LOG_ERR));
 }
 
 static void test_get_timezones(void) {
@@ -182,7 +182,7 @@ static void test_get_timezones(void) {
         assert_se(r == 0);
 
         STRV_FOREACH(zone, zones)
-                assert_se(timezone_is_valid(*zone));
+                assert_se(timezone_is_valid(*zone, LOG_ERR));
 }
 
 static void test_usec_add(void) {
index 3fd4ac9e5dae532eedd90e6017178aba968ddd87..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) {
@@ -636,8 +634,8 @@ static void test_install_printf(void) {
 
         assert_se(specifier_machine_id('m', NULL, NULL, &mid) >= 0 && mid);
         assert_se(specifier_boot_id('b', NULL, NULL, &bid) >= 0 && bid);
-        assert_se((host = gethostname_malloc()));
-        assert_se((user = uid_to_name(getuid())));
+        assert_se(host = gethostname_malloc());
+        assert_se(user = uid_to_name(getuid()));
         assert_se(asprintf(&uid, UID_FMT, getuid()) >= 0);
 
 #define expect(src, pattern, result)                                    \
@@ -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 300a1c5a82ea7ce5447c3937f44e1d164339beaa..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"
@@ -24,6 +25,7 @@
 #include "string-util.h"
 #include "test-helper.h"
 #include "tests.h"
+#include "unit-def.h"
 #include "unit-name.h"
 #include "unit-printf.h"
 #include "unit.h"
@@ -96,7 +98,7 @@ static void test_unit_name_from_path_one(const char *path, const char *suffix, c
                 _cleanup_free_ char *k = NULL;
                 assert_se(unit_name_to_path(t, &k) == 0);
                 puts(strna(k));
-                assert_se(path_equal(k, isempty(path) ? "/" : path));
+                assert_se(path_equal(k, empty_to_root(path)));
         }
 }
 
@@ -124,7 +126,7 @@ static void test_unit_name_from_path_instance_one(const char *pattern, const cha
 
                 assert_se(unit_name_to_instance(t, &k) > 0);
                 assert_se(unit_name_path_unescape(k, &v) == 0);
-                assert_se(path_equal(v, isempty(path) ? "/" : path));
+                assert_se(path_equal(v, empty_to_root(path)));
         }
 }
 
@@ -519,6 +521,299 @@ static void test_unit_name_to_prefix(void) {
         test_unit_name_to_prefix_one("@.mount", -EINVAL, NULL);
 }
 
+static void test_unit_name_from_dbus_path_one(const char *input, int ret, const char *output) {
+        _cleanup_free_ char *k = NULL;
+
+        assert_se(unit_name_from_dbus_path(input, &k) == ret);
+        assert_se(streq_ptr(k, output));
+}
+
+static void test_unit_name_from_dbus_path(void) {
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/dbus_2esocket", 0, "dbus.socket");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/_2d_2emount", 0, "-.mount");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/_2d_2eslice", 0, "-.slice");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/accounts_2ddaemon_2eservice", 0, "accounts-daemon.service");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/auditd_2eservice", 0, "auditd.service");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/basic_2etarget", 0, "basic.target");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/bluetooth_2etarget", 0, "bluetooth.target");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/boot_2eautomount", 0, "boot.automount");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/boot_2emount", 0, "boot.mount");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/btrfs_2emount", 0, "btrfs.mount");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/cryptsetup_2dpre_2etarget", 0, "cryptsetup-pre.target");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/cryptsetup_2etarget", 0, "cryptsetup.target");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/dbus_2eservice", 0, "dbus.service");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/dbus_2esocket", 0, "dbus.socket");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/dev_2dcdrom_2edevice", 0, "dev-cdrom.device");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/dev_2ddisk_2dby_5cx2did_2data_5cx2dINTEL_5fSSDSA2M120G2GC_5fCVPO044405HH120QGN_2edevice", 0, "dev-disk-by\\x2did-ata\\x2dINTEL_SSDSA2M120G2GC_CVPO044405HH120QGN.device");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/dev_2ddisk_2dby_5cx2did_2data_5cx2dINTEL_5fSSDSA2M120G2GC_5fCVPO044405HH120QGN_5cx2dpart1_2edevice", 0, "dev-disk-by\\x2did-ata\\x2dINTEL_SSDSA2M120G2GC_CVPO044405HH120QGN\\x2dpart1.device");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/dev_2ddisk_2dby_5cx2did_2data_5cx2dINTEL_5fSSDSA2M160G2GC_5fCVPO951003RY160AGN_2edevice", 0, "dev-disk-by\\x2did-ata\\x2dINTEL_SSDSA2M160G2GC_CVPO951003RY160AGN.device");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/dev_2ddisk_2dby_5cx2did_2data_5cx2dINTEL_5fSSDSA2M160G2GC_5fCVPO951003RY160AGN_5cx2dpart1_2edevice", 0, "dev-disk-by\\x2did-ata\\x2dINTEL_SSDSA2M160G2GC_CVPO951003RY160AGN\\x2dpart1.device");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/dev_2ddisk_2dby_5cx2did_2data_5cx2dINTEL_5fSSDSA2M160G2GC_5fCVPO951003RY160AGN_5cx2dpart2_2edevice", 0, "dev-disk-by\\x2did-ata\\x2dINTEL_SSDSA2M160G2GC_CVPO951003RY160AGN\\x2dpart2.device");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/dev_2ddisk_2dby_5cx2did_2data_5cx2dINTEL_5fSSDSA2M160G2GC_5fCVPO951003RY160AGN_5cx2dpart3_2edevice", 0, "dev-disk-by\\x2did-ata\\x2dINTEL_SSDSA2M160G2GC_CVPO951003RY160AGN\\x2dpart3.device");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/dev_2ddisk_2dby_5cx2did_2data_5cx2dTSSTcorp_5fCDDVDW_5fTS_5cx2dL633C_5fR6176GLZB14646_2edevice", 0, "dev-disk-by\\x2did-ata\\x2dTSSTcorp_CDDVDW_TS\\x2dL633C_R6176GLZB14646.device");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/dev_2ddisk_2dby_5cx2did_2dwwn_5cx2d0x50015179591245ae_2edevice", 0, "dev-disk-by\\x2did-wwn\\x2d0x50015179591245ae.device");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/dev_2ddisk_2dby_5cx2did_2dwwn_5cx2d0x50015179591245ae_5cx2dpart1_2edevice", 0, "dev-disk-by\\x2did-wwn\\x2d0x50015179591245ae\\x2dpart1.device");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/dev_2ddisk_2dby_5cx2did_2dwwn_5cx2d0x50015179591245ae_5cx2dpart2_2edevice", 0, "dev-disk-by\\x2did-wwn\\x2d0x50015179591245ae\\x2dpart2.device");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/dev_2ddisk_2dby_5cx2did_2dwwn_5cx2d0x50015179591245ae_5cx2dpart3_2edevice", 0, "dev-disk-by\\x2did-wwn\\x2d0x50015179591245ae\\x2dpart3.device");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/dev_2ddisk_2dby_5cx2did_2dwwn_5cx2d0x500151795946eab5_2edevice", 0, "dev-disk-by\\x2did-wwn\\x2d0x500151795946eab5.device");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/dev_2ddisk_2dby_5cx2did_2dwwn_5cx2d0x500151795946eab5_5cx2dpart1_2edevice", 0, "dev-disk-by\\x2did-wwn\\x2d0x500151795946eab5\\x2dpart1.device");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/dev_2ddisk_2dby_5cx2dlabel_2d_5cxe3_5cx82_5cxb7_5cxe3_5cx82_5cxb9_5cxe3_5cx83_5cx86_5cxe3_5cx83_5cxa0_5cxe3_5cx81_5cxa7_5cxe4_5cxba_5cx88_5cxe7_5cxb4_5cx84_5cxe6_5cxb8_5cx88_5cxe3_5cx81_5cxbf_2edevice", 0, "dev-disk-by\\x2dlabel-\\xe3\\x82\\xb7\\xe3\\x82\\xb9\\xe3\\x83\\x86\\xe3\\x83\\xa0\\xe3\\x81\\xa7\\xe4\\xba\\x88\\xe7\\xb4\\x84\\xe6\\xb8\\x88\\xe3\\x81\\xbf.device");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/dev_2ddisk_2dby_5cx2dpartuuid_2d59834e50_5cx2d01_2edevice", 0, "dev-disk-by\\x2dpartuuid-59834e50\\x2d01.device");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/dev_2ddisk_2dby_5cx2dpartuuid_2d63e2a7b3_5cx2d01_2edevice", 0, "dev-disk-by\\x2dpartuuid-63e2a7b3\\x2d01.device");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/dev_2ddisk_2dby_5cx2dpartuuid_2d63e2a7b3_5cx2d02_2edevice", 0, "dev-disk-by\\x2dpartuuid-63e2a7b3\\x2d02.device");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/dev_2ddisk_2dby_5cx2dpartuuid_2d63e2a7b3_5cx2d03_2edevice", 0, "dev-disk-by\\x2dpartuuid-63e2a7b3\\x2d03.device");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/dev_2ddisk_2dby_5cx2dpath_2dpci_5cx2d0000_3a00_3a1f_2e2_5cx2data_5cx2d1_2edevice", 0, "dev-disk-by\\x2dpath-pci\\x2d0000:00:1f.2\\x2data\\x2d1.device");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/dev_2ddisk_2dby_5cx2dpath_2dpci_5cx2d0000_3a00_3a1f_2e2_5cx2data_5cx2d1_5cx2dpart1_2edevice", 0, "dev-disk-by\\x2dpath-pci\\x2d0000:00:1f.2\\x2data\\x2d1\\x2dpart1.device");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/dev_2ddisk_2dby_5cx2dpath_2dpci_5cx2d0000_3a00_3a1f_2e2_5cx2data_5cx2d1_5cx2dpart2_2edevice", 0, "dev-disk-by\\x2dpath-pci\\x2d0000:00:1f.2\\x2data\\x2d1\\x2dpart2.device");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/dev_2ddisk_2dby_5cx2dpath_2dpci_5cx2d0000_3a00_3a1f_2e2_5cx2data_5cx2d1_5cx2dpart3_2edevice", 0, "dev-disk-by\\x2dpath-pci\\x2d0000:00:1f.2\\x2data\\x2d1\\x2dpart3.device");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/dev_2ddisk_2dby_5cx2dpath_2dpci_5cx2d0000_3a00_3a1f_2e2_5cx2data_5cx2d2_2edevice", 0, "dev-disk-by\\x2dpath-pci\\x2d0000:00:1f.2\\x2data\\x2d2.device");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/dev_2ddisk_2dby_5cx2dpath_2dpci_5cx2d0000_3a00_3a1f_2e2_5cx2data_5cx2d6_2edevice", 0, "dev-disk-by\\x2dpath-pci\\x2d0000:00:1f.2\\x2data\\x2d6.device");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/dev_2ddisk_2dby_5cx2dpath_2dpci_5cx2d0000_3a00_3a1f_2e2_5cx2data_5cx2d6_5cx2dpart1_2edevice", 0, "dev-disk-by\\x2dpath-pci\\x2d0000:00:1f.2\\x2data\\x2d6\\x2dpart1.device");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/dev_2ddisk_2dby_5cx2duuid_2d1A34E3F034E3CD37_2edevice", 0, "dev-disk-by\\x2duuid-1A34E3F034E3CD37.device");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/dev_2ddisk_2dby_5cx2duuid_2dB670EBFE70EBC2EB_2edevice", 0, "dev-disk-by\\x2duuid-B670EBFE70EBC2EB.device");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/dev_2ddisk_2dby_5cx2duuid_2dFCD4F509D4F4C6C4_2edevice", 0, "dev-disk-by\\x2duuid-FCD4F509D4F4C6C4.device");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/dev_2ddisk_2dby_5cx2duuid_2db49ead57_5cx2d907c_5cx2d446c_5cx2db405_5cx2d5ca6cd865f5e_2edevice", 0, "dev-disk-by\\x2duuid-b49ead57\\x2d907c\\x2d446c\\x2db405\\x2d5ca6cd865f5e.device");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/dev_2dhugepages_2emount", 0, "dev-hugepages.mount");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/dev_2dmqueue_2emount", 0, "dev-mqueue.mount");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/dev_2drfkill_2edevice", 0, "dev-rfkill.device");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/dev_2dsda1_2edevice", 0, "dev-sda1.device");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/dev_2dsda2_2edevice", 0, "dev-sda2.device");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/dev_2dsda3_2edevice", 0, "dev-sda3.device");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/dev_2dsda_2edevice", 0, "dev-sda.device");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/dev_2dsdb1_2edevice", 0, "dev-sdb1.device");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/dev_2dsdb_2edevice", 0, "dev-sdb.device");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/dev_2dsr0_2edevice", 0, "dev-sr0.device");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/dev_2dttyS0_2edevice", 0, "dev-ttyS0.device");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/dev_2dttyS10_2edevice", 0, "dev-ttyS10.device");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/dev_2dttyS11_2edevice", 0, "dev-ttyS11.device");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/dev_2dttyS12_2edevice", 0, "dev-ttyS12.device");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/dev_2dttyS13_2edevice", 0, "dev-ttyS13.device");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/dev_2dttyS14_2edevice", 0, "dev-ttyS14.device");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/dev_2dttyS15_2edevice", 0, "dev-ttyS15.device");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/dev_2dttyS16_2edevice", 0, "dev-ttyS16.device");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/dev_2dttyS17_2edevice", 0, "dev-ttyS17.device");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/dev_2dttyS18_2edevice", 0, "dev-ttyS18.device");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/dev_2dttyS19_2edevice", 0, "dev-ttyS19.device");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/dev_2dttyS1_2edevice", 0, "dev-ttyS1.device");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/dev_2dttyS20_2edevice", 0, "dev-ttyS20.device");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/dev_2dttyS21_2edevice", 0, "dev-ttyS21.device");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/dev_2dttyS22_2edevice", 0, "dev-ttyS22.device");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/dev_2dttyS23_2edevice", 0, "dev-ttyS23.device");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/dev_2dttyS24_2edevice", 0, "dev-ttyS24.device");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/dev_2dttyS25_2edevice", 0, "dev-ttyS25.device");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/dev_2dttyS26_2edevice", 0, "dev-ttyS26.device");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/dev_2dttyS27_2edevice", 0, "dev-ttyS27.device");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/dev_2dttyS28_2edevice", 0, "dev-ttyS28.device");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/dev_2dttyS29_2edevice", 0, "dev-ttyS29.device");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/dev_2dttyS2_2edevice", 0, "dev-ttyS2.device");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/dev_2dttyS30_2edevice", 0, "dev-ttyS30.device");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/dev_2dttyS31_2edevice", 0, "dev-ttyS31.device");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/dev_2dttyS3_2edevice", 0, "dev-ttyS3.device");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/dev_2dttyS4_2edevice", 0, "dev-ttyS4.device");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/dev_2dttyS5_2edevice", 0, "dev-ttyS5.device");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/dev_2dttyS6_2edevice", 0, "dev-ttyS6.device");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/dev_2dttyS7_2edevice", 0, "dev-ttyS7.device");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/dev_2dttyS8_2edevice", 0, "dev-ttyS8.device");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/dev_2dttyS9_2edevice", 0, "dev-ttyS9.device");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/dracut_2dcmdline_2eservice", 0, "dracut-cmdline.service");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/dracut_2dinitqueue_2eservice", 0, "dracut-initqueue.service");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/dracut_2dmount_2eservice", 0, "dracut-mount.service");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/dracut_2dpre_2dmount_2eservice", 0, "dracut-pre-mount.service");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/dracut_2dpre_2dpivot_2eservice", 0, "dracut-pre-pivot.service");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/dracut_2dpre_2dtrigger_2eservice", 0, "dracut-pre-trigger.service");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/dracut_2dpre_2dudev_2eservice", 0, "dracut-pre-udev.service");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/dracut_2dshutdown_2eservice", 0, "dracut-shutdown.service");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/ebtables_2eservice", 0, "ebtables.service");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/emergency_2eservice", 0, "emergency.service");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/emergency_2etarget", 0, "emergency.target");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/fedora_2dimport_2dstate_2eservice", 0, "fedora-import-state.service");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/fedora_2dreadonly_2eservice", 0, "fedora-readonly.service");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/firewalld_2eservice", 0, "firewalld.service");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/getty_2dpre_2etarget", 0, "getty-pre.target");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/getty_2etarget", 0, "getty.target");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/getty_40tty1_2eservice", 0, "getty@tty1.service");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/graphical_2etarget", 0, "graphical.target");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/home_2emount", 0, "home.mount");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/init_2escope", 0, "init.scope");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/initrd_2dcleanup_2eservice", 0, "initrd-cleanup.service");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/initrd_2dfs_2etarget", 0, "initrd-fs.target");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/initrd_2dparse_2detc_2eservice", 0, "initrd-parse-etc.service");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/initrd_2droot_2ddevice_2etarget", 0, "initrd-root-device.target");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/initrd_2droot_2dfs_2etarget", 0, "initrd-root-fs.target");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/initrd_2dswitch_2droot_2eservice", 0, "initrd-switch-root.service");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/initrd_2dswitch_2droot_2etarget", 0, "initrd-switch-root.target");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/initrd_2dudevadm_2dcleanup_2ddb_2eservice", 0, "initrd-udevadm-cleanup-db.service");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/initrd_2etarget", 0, "initrd.target");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/ip6tables_2eservice", 0, "ip6tables.service");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/ipset_2eservice", 0, "ipset.service");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/iptables_2eservice", 0, "iptables.service");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/irqbalance_2eservice", 0, "irqbalance.service");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/kmod_2dstatic_2dnodes_2eservice", 0, "kmod-static-nodes.service");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/ldconfig_2eservice", 0, "ldconfig.service");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/lightdm_2eservice", 0, "lightdm.service");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/livesys_2dlate_2eservice", 0, "livesys-late.service");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/lm_5fsensors_2eservice", 0, "lm_sensors.service");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/local_2dfs_2dpre_2etarget", 0, "local-fs-pre.target");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/local_2dfs_2etarget", 0, "local-fs.target");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/machines_2etarget", 0, "machines.target");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/mcelog_2eservice", 0, "mcelog.service");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/multi_2duser_2etarget", 0, "multi-user.target");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/network_2dpre_2etarget", 0, "network-pre.target");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/network_2etarget", 0, "network.target");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/nss_2dlookup_2etarget", 0, "nss-lookup.target");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/nss_2duser_2dlookup_2etarget", 0, "nss-user-lookup.target");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/paths_2etarget", 0, "paths.target");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/plymouth_2dquit_2dwait_2eservice", 0, "plymouth-quit-wait.service");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/plymouth_2dquit_2eservice", 0, "plymouth-quit.service");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/plymouth_2dstart_2eservice", 0, "plymouth-start.service");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/polkit_2eservice", 0, "polkit.service");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/proc_2dsys_2dfs_2dbinfmt_5fmisc_2eautomount", 0, "proc-sys-fs-binfmt_misc.automount");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/proc_2dsys_2dfs_2dbinfmt_5fmisc_2emount", 0, "proc-sys-fs-binfmt_misc.mount");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/rc_2dlocal_2eservice", 0, "rc-local.service");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/remote_2dcryptsetup_2etarget", 0, "remote-cryptsetup.target");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/remote_2dfs_2dpre_2etarget", 0, "remote-fs-pre.target");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/remote_2dfs_2etarget", 0, "remote-fs.target");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/rescue_2eservice", 0, "rescue.service");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/rescue_2etarget", 0, "rescue.target");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/run_2duser_2d1000_2emount", 0, "run-user-1000.mount");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/session_2d2_2escope", 0, "session-2.scope");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/shutdown_2etarget", 0, "shutdown.target");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/slices_2etarget", 0, "slices.target");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/smartd_2eservice", 0, "smartd.service");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/sockets_2etarget", 0, "sockets.target");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/sound_2etarget", 0, "sound.target");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/sshd_2dkeygen_2etarget", 0, "sshd-keygen.target");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/sshd_2dkeygen_40ecdsa_2eservice", 0, "sshd-keygen@ecdsa.service");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/sshd_2dkeygen_40ed25519_2eservice", 0, "sshd-keygen@ed25519.service");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/sshd_2dkeygen_40rsa_2eservice", 0, "sshd-keygen@rsa.service");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/sshd_2eservice", 0, "sshd.service");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/swap_2etarget", 0, "swap.target");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/sys_2ddevices_2dpci0000_3a00_2d0000_3a00_3a02_2e0_2dbacklight_2dacpi_5fvideo0_2edevice", 0, "sys-devices-pci0000:00-0000:00:02.0-backlight-acpi_video0.device");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/sys_2ddevices_2dpci0000_3a00_2d0000_3a00_3a02_2e0_2ddrm_2dcard0_2dcard0_5cx2dLVDS_5cx2d1_2dintel_5fbacklight_2edevice", 0, "sys-devices-pci0000:00-0000:00:02.0-drm-card0-card0\\x2dLVDS\\x2d1-intel_backlight.device");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/sys_2ddevices_2dpci0000_3a00_2d0000_3a00_3a1a_2e0_2dusb1_2d1_5cx2d1_2d1_5cx2d1_2e6_2d1_5cx2d1_2e6_3a1_2e0_2dbluetooth_2dhci0_2edevice", 0, "sys-devices-pci0000:00-0000:00:1a.0-usb1-1\\x2d1-1\\x2d1.6-1\\x2d1.6:1.0-bluetooth-hci0.device");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/sys_2ddevices_2dpci0000_3a00_2d0000_3a00_3a1b_2e0_2dsound_2dcard0_2edevice", 0, "sys-devices-pci0000:00-0000:00:1b.0-sound-card0.device");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/sys_2ddevices_2dpci0000_3a00_2d0000_3a00_3a1c_2e0_2d0000_3a02_3a00_2e0_2dnet_2dwlp2s0_2edevice", 0, "sys-devices-pci0000:00-0000:00:1c.0-0000:02:00.0-net-wlp2s0.device");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/sys_2ddevices_2dpci0000_3a00_2d0000_3a00_3a1c_2e2_2d0000_3a04_3a00_2e0_2dnet_2denp4s0_2edevice", 0, "sys-devices-pci0000:00-0000:00:1c.2-0000:04:00.0-net-enp4s0.device");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/sys_2ddevices_2dpci0000_3a00_2d0000_3a00_3a1f_2e2_2data1_2dhost0_2dtarget0_3a0_3a0_2d0_3a0_3a0_3a0_2dblock_2dsda_2dsda1_2edevice", 0, "sys-devices-pci0000:00-0000:00:1f.2-ata1-host0-target0:0:0-0:0:0:0-block-sda-sda1.device");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/sys_2ddevices_2dpci0000_3a00_2d0000_3a00_3a1f_2e2_2data1_2dhost0_2dtarget0_3a0_3a0_2d0_3a0_3a0_3a0_2dblock_2dsda_2dsda2_2edevice", 0, "sys-devices-pci0000:00-0000:00:1f.2-ata1-host0-target0:0:0-0:0:0:0-block-sda-sda2.device");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/sys_2ddevices_2dpci0000_3a00_2d0000_3a00_3a1f_2e2_2data1_2dhost0_2dtarget0_3a0_3a0_2d0_3a0_3a0_3a0_2dblock_2dsda_2dsda3_2edevice", 0, "sys-devices-pci0000:00-0000:00:1f.2-ata1-host0-target0:0:0-0:0:0:0-block-sda-sda3.device");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/sys_2ddevices_2dpci0000_3a00_2d0000_3a00_3a1f_2e2_2data1_2dhost0_2dtarget0_3a0_3a0_2d0_3a0_3a0_3a0_2dblock_2dsda_2edevice", 0, "sys-devices-pci0000:00-0000:00:1f.2-ata1-host0-target0:0:0-0:0:0:0-block-sda.device");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/sys_2ddevices_2dpci0000_3a00_2d0000_3a00_3a1f_2e2_2data2_2dhost1_2dtarget1_3a0_3a0_2d1_3a0_3a0_3a0_2dblock_2dsr0_2edevice", 0, "sys-devices-pci0000:00-0000:00:1f.2-ata2-host1-target1:0:0-1:0:0:0-block-sr0.device");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/sys_2ddevices_2dpci0000_3a00_2d0000_3a00_3a1f_2e2_2data6_2dhost5_2dtarget5_3a0_3a0_2d5_3a0_3a0_3a0_2dblock_2dsdb_2dsdb1_2edevice", 0, "sys-devices-pci0000:00-0000:00:1f.2-ata6-host5-target5:0:0-5:0:0:0-block-sdb-sdb1.device");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/sys_2ddevices_2dpci0000_3a00_2d0000_3a00_3a1f_2e2_2data6_2dhost5_2dtarget5_3a0_3a0_2d5_3a0_3a0_3a0_2dblock_2dsdb_2edevice", 0, "sys-devices-pci0000:00-0000:00:1f.2-ata6-host5-target5:0:0-5:0:0:0-block-sdb.device");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/sys_2ddevices_2dplatform_2dserial8250_2dtty_2dttyS0_2edevice", 0, "sys-devices-platform-serial8250-tty-ttyS0.device");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/sys_2ddevices_2dplatform_2dserial8250_2dtty_2dttyS10_2edevice", 0, "sys-devices-platform-serial8250-tty-ttyS10.device");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/sys_2ddevices_2dplatform_2dserial8250_2dtty_2dttyS11_2edevice", 0, "sys-devices-platform-serial8250-tty-ttyS11.device");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/sys_2ddevices_2dplatform_2dserial8250_2dtty_2dttyS12_2edevice", 0, "sys-devices-platform-serial8250-tty-ttyS12.device");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/sys_2ddevices_2dplatform_2dserial8250_2dtty_2dttyS13_2edevice", 0, "sys-devices-platform-serial8250-tty-ttyS13.device");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/sys_2ddevices_2dplatform_2dserial8250_2dtty_2dttyS14_2edevice", 0, "sys-devices-platform-serial8250-tty-ttyS14.device");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/sys_2ddevices_2dplatform_2dserial8250_2dtty_2dttyS15_2edevice", 0, "sys-devices-platform-serial8250-tty-ttyS15.device");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/sys_2ddevices_2dplatform_2dserial8250_2dtty_2dttyS16_2edevice", 0, "sys-devices-platform-serial8250-tty-ttyS16.device");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/sys_2ddevices_2dplatform_2dserial8250_2dtty_2dttyS17_2edevice", 0, "sys-devices-platform-serial8250-tty-ttyS17.device");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/sys_2ddevices_2dplatform_2dserial8250_2dtty_2dttyS18_2edevice", 0, "sys-devices-platform-serial8250-tty-ttyS18.device");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/sys_2ddevices_2dplatform_2dserial8250_2dtty_2dttyS19_2edevice", 0, "sys-devices-platform-serial8250-tty-ttyS19.device");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/sys_2ddevices_2dplatform_2dserial8250_2dtty_2dttyS1_2edevice", 0, "sys-devices-platform-serial8250-tty-ttyS1.device");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/sys_2ddevices_2dplatform_2dserial8250_2dtty_2dttyS20_2edevice", 0, "sys-devices-platform-serial8250-tty-ttyS20.device");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/sys_2ddevices_2dplatform_2dserial8250_2dtty_2dttyS21_2edevice", 0, "sys-devices-platform-serial8250-tty-ttyS21.device");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/sys_2ddevices_2dplatform_2dserial8250_2dtty_2dttyS22_2edevice", 0, "sys-devices-platform-serial8250-tty-ttyS22.device");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/sys_2ddevices_2dplatform_2dserial8250_2dtty_2dttyS23_2edevice", 0, "sys-devices-platform-serial8250-tty-ttyS23.device");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/sys_2ddevices_2dplatform_2dserial8250_2dtty_2dttyS24_2edevice", 0, "sys-devices-platform-serial8250-tty-ttyS24.device");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/sys_2ddevices_2dplatform_2dserial8250_2dtty_2dttyS25_2edevice", 0, "sys-devices-platform-serial8250-tty-ttyS25.device");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/sys_2ddevices_2dplatform_2dserial8250_2dtty_2dttyS26_2edevice", 0, "sys-devices-platform-serial8250-tty-ttyS26.device");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/sys_2ddevices_2dplatform_2dserial8250_2dtty_2dttyS27_2edevice", 0, "sys-devices-platform-serial8250-tty-ttyS27.device");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/sys_2ddevices_2dplatform_2dserial8250_2dtty_2dttyS28_2edevice", 0, "sys-devices-platform-serial8250-tty-ttyS28.device");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/sys_2ddevices_2dplatform_2dserial8250_2dtty_2dttyS29_2edevice", 0, "sys-devices-platform-serial8250-tty-ttyS29.device");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/sys_2ddevices_2dplatform_2dserial8250_2dtty_2dttyS2_2edevice", 0, "sys-devices-platform-serial8250-tty-ttyS2.device");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/sys_2ddevices_2dplatform_2dserial8250_2dtty_2dttyS30_2edevice", 0, "sys-devices-platform-serial8250-tty-ttyS30.device");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/sys_2ddevices_2dplatform_2dserial8250_2dtty_2dttyS31_2edevice", 0, "sys-devices-platform-serial8250-tty-ttyS31.device");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/sys_2ddevices_2dplatform_2dserial8250_2dtty_2dttyS3_2edevice", 0, "sys-devices-platform-serial8250-tty-ttyS3.device");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/sys_2ddevices_2dplatform_2dserial8250_2dtty_2dttyS4_2edevice", 0, "sys-devices-platform-serial8250-tty-ttyS4.device");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/sys_2ddevices_2dplatform_2dserial8250_2dtty_2dttyS5_2edevice", 0, "sys-devices-platform-serial8250-tty-ttyS5.device");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/sys_2ddevices_2dplatform_2dserial8250_2dtty_2dttyS6_2edevice", 0, "sys-devices-platform-serial8250-tty-ttyS6.device");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/sys_2ddevices_2dplatform_2dserial8250_2dtty_2dttyS7_2edevice", 0, "sys-devices-platform-serial8250-tty-ttyS7.device");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/sys_2ddevices_2dplatform_2dserial8250_2dtty_2dttyS8_2edevice", 0, "sys-devices-platform-serial8250-tty-ttyS8.device");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/sys_2ddevices_2dplatform_2dserial8250_2dtty_2dttyS9_2edevice", 0, "sys-devices-platform-serial8250-tty-ttyS9.device");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/sys_2ddevices_2dvirtual_2dmisc_2drfkill_2edevice", 0, "sys-devices-virtual-misc-rfkill.device");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/sys_2dfs_2dfuse_2dconnections_2emount", 0, "sys-fs-fuse-connections.mount");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/sys_2dkernel_2dconfig_2emount", 0, "sys-kernel-config.mount");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/sys_2dkernel_2ddebug_2emount", 0, "sys-kernel-debug.mount");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/sys_2dmodule_2dconfigfs_2edevice", 0, "sys-module-configfs.device");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/sys_2dsubsystem_2dbluetooth_2ddevices_2dhci0_2edevice", 0, "sys-subsystem-bluetooth-devices-hci0.device");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/sys_2dsubsystem_2dnet_2ddevices_2denp4s0_2edevice", 0, "sys-subsystem-net-devices-enp4s0.device");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/sys_2dsubsystem_2dnet_2ddevices_2dwlp2s0_2edevice", 0, "sys-subsystem-net-devices-wlp2s0.device");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/sysinit_2etarget", 0, "sysinit.target");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/syslog_2eservice", 0, "syslog.service");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/syslog_2esocket", 0, "syslog.socket");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/syslog_2etarget", 0, "syslog.target");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/sysroot_2emount", 0, "sysroot.mount");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/system_2dgetty_2eslice", 0, "system-getty.slice");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/system_2dsshd_5cx2dkeygen_2eslice", 0, "system-sshd\\x2dkeygen.slice");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/system_2dsystemd_5cx2dbacklight_2eslice", 0, "system-systemd\\x2dbacklight.slice");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/system_2dsystemd_5cx2dcoredump_2eslice", 0, "system-systemd\\x2dcoredump.slice");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/system_2duser_5cx2druntime_5cx2ddir_2eslice", 0, "system-user\\x2druntime\\x2ddir.slice");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/system_2eslice", 0, "system.slice");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/systemd_2dask_2dpassword_2dconsole_2epath", 0, "systemd-ask-password-console.path");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/systemd_2dask_2dpassword_2dconsole_2eservice", 0, "systemd-ask-password-console.service");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/systemd_2dask_2dpassword_2dwall_2epath", 0, "systemd-ask-password-wall.path");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/systemd_2dask_2dpassword_2dwall_2eservice", 0, "systemd-ask-password-wall.service");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/systemd_2dbacklight_40backlight_3aacpi_5fvideo0_2eservice", 0, "systemd-backlight@backlight:acpi_video0.service");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/systemd_2dbacklight_40backlight_3aintel_5fbacklight_2eservice", 0, "systemd-backlight@backlight:intel_backlight.service");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/systemd_2dbinfmt_2eservice", 0, "systemd-binfmt.service");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/systemd_2dcoredump_2esocket", 0, "systemd-coredump.socket");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/systemd_2dcoredump_400_2eservice", 0, "systemd-coredump@0.service");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/systemd_2dfirstboot_2eservice", 0, "systemd-firstboot.service");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/systemd_2dfsck_2droot_2eservice", 0, "systemd-fsck-root.service");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/systemd_2dhwdb_2dupdate_2eservice", 0, "systemd-hwdb-update.service");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/systemd_2dinitctl_2eservice", 0, "systemd-initctl.service");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/systemd_2dinitctl_2esocket", 0, "systemd-initctl.socket");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/systemd_2djournal_2dcatalog_2dupdate_2eservice", 0, "systemd-journal-catalog-update.service");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/systemd_2djournal_2dflush_2eservice", 0, "systemd-journal-flush.service");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/systemd_2djournald_2daudit_2esocket", 0, "systemd-journald-audit.socket");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/systemd_2djournald_2ddev_2dlog_2esocket", 0, "systemd-journald-dev-log.socket");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/systemd_2djournald_2eservice", 0, "systemd-journald.service");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/systemd_2djournald_2esocket", 0, "systemd-journald.socket");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/systemd_2dlogind_2eservice", 0, "systemd-logind.service");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/systemd_2dmachine_2did_2dcommit_2eservice", 0, "systemd-machine-id-commit.service");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/systemd_2dmodules_2dload_2eservice", 0, "systemd-modules-load.service");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/systemd_2dnetworkd_2eservice", 0, "systemd-networkd.service");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/systemd_2dnetworkd_2esocket", 0, "systemd-networkd.socket");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/systemd_2drandom_2dseed_2eservice", 0, "systemd-random-seed.service");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/systemd_2dremount_2dfs_2eservice", 0, "systemd-remount-fs.service");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/systemd_2dresolved_2eservice", 0, "systemd-resolved.service");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/systemd_2drfkill_2eservice", 0, "systemd-rfkill.service");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/systemd_2drfkill_2esocket", 0, "systemd-rfkill.socket");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/systemd_2dsysctl_2eservice", 0, "systemd-sysctl.service");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/systemd_2dsysusers_2eservice", 0, "systemd-sysusers.service");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/systemd_2dtimesyncd_2eservice", 0, "systemd-timesyncd.service");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/systemd_2dtmpfiles_2dclean_2eservice", 0, "systemd-tmpfiles-clean.service");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/systemd_2dtmpfiles_2dclean_2etimer", 0, "systemd-tmpfiles-clean.timer");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/systemd_2dtmpfiles_2dsetup_2ddev_2eservice", 0, "systemd-tmpfiles-setup-dev.service");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/systemd_2dtmpfiles_2dsetup_2eservice", 0, "systemd-tmpfiles-setup.service");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/systemd_2dudev_2dtrigger_2eservice", 0, "systemd-udev-trigger.service");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/systemd_2dudevd_2dcontrol_2esocket", 0, "systemd-udevd-control.socket");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/systemd_2dudevd_2dkernel_2esocket", 0, "systemd-udevd-kernel.socket");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/systemd_2dudevd_2eservice", 0, "systemd-udevd.service");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/systemd_2dupdate_2ddone_2eservice", 0, "systemd-update-done.service");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/systemd_2dupdate_2dutmp_2drunlevel_2eservice", 0, "systemd-update-utmp-runlevel.service");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/systemd_2dupdate_2dutmp_2eservice", 0, "systemd-update-utmp.service");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/systemd_2duser_2dsessions_2eservice", 0, "systemd-user-sessions.service");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/systemd_2dvconsole_2dsetup_2eservice", 0, "systemd-vconsole-setup.service");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/time_2dsync_2etarget", 0, "time-sync.target");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/timers_2etarget", 0, "timers.target");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/tmp_2emount", 0, "tmp.mount");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/umount_2etarget", 0, "umount.target");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/unbound_2danchor_2eservice", 0, "unbound-anchor.service");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/unbound_2danchor_2etimer", 0, "unbound-anchor.timer");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/upower_2eservice", 0, "upower.service");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/user_2d1000_2eslice", 0, "user-1000.slice");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/user_2druntime_2ddir_401000_2eservice", 0, "user-runtime-dir@1000.service");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/user_2eslice", 0, "user.slice");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/user_401000_2eservice", 0, "user@1000.service");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/usr_2dlocal_2dtexlive_2emount", 0, "usr-local-texlive.mount");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/var_2dlib_2dmachines_2emount", 0, "var-lib-machines.mount");
+        test_unit_name_from_dbus_path_one("/org/freedesktop/systemd1/unit/wpa_5fsupplicant_2eservice", 0, "wpa_supplicant.service");
+}
+
 int main(int argc, char* argv[]) {
         _cleanup_(rm_rf_physical_and_freep) char *runtime_dir = NULL;
         int r, rc = 0;
@@ -553,6 +848,7 @@ int main(int argc, char* argv[]) {
         test_unit_name_template();
         test_unit_name_path_unescape();
         test_unit_name_to_prefix();
+        test_unit_name_from_dbus_path();
 
         return rc;
 }
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 59a642cac75b5305627d140f43728dd923ef99ef..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,
@@ -532,10 +511,8 @@ static int property_get_ntp(
 
 static int method_set_timezone(sd_bus_message *m, void *userdata, sd_bus_error *error) {
         Context *c = userdata;
+        int interactive, r;
         const char *z;
-        int interactive;
-        char *t;
-        int r;
 
         assert(m);
         assert(c);
@@ -544,7 +521,7 @@ static int method_set_timezone(sd_bus_message *m, void *userdata, sd_bus_error *
         if (r < 0)
                 return r;
 
-        if (!timezone_is_valid(z))
+        if (!timezone_is_valid(z, LOG_DEBUG))
                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid time zone '%s'", z);
 
         if (streq_ptr(z, c->zone))
@@ -564,12 +541,9 @@ 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 */
 
-        t = strdup(z);
-        if (!t)
-                return -ENOMEM;
-
-        free(c->zone);
-        c->zone = t;
+        r = free_and_strdup(&c->zone, z);
+        if (r < 0)
+                return r;
 
         /* 1. Write new configuration file */
         r = context_write_data_timezone(c);
index 1932043fb95c9ed439ac5def6a8d0b229bc44e51..f2527f52e43f328f82bffd0bb0f06af58b0c8f7d 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(
@@ -169,100 +169,6 @@ static const sd_bus_vtable manager_vtable[] = {
         SD_BUS_VTABLE_END
 };
 
-static int reload_dbus_handler(sd_bus_message *m, void *userdata, sd_bus_error *ret_error) {
-        const sd_bus_error *e;
-        int r;
-
-        assert(m);
-
-        e = sd_bus_message_get_error(m);
-        if (e) {
-                log_error_errno(sd_bus_error_get_errno(e), "Failed to reload DBus configuration: %s", e->message);
-                return 1;
-        }
-
-        /* Here, use the default request name handler to avoid an infinite loop of reloading and requesting. */
-        r = sd_bus_request_name_async(sd_bus_message_get_bus(m), NULL, "org.freedesktop.timesync1", 0, NULL, NULL);
-        if (r < 0)
-                log_error_errno(r, "Failed to request name: %m");
-
-        return 1;
-}
-
-static int request_name_handler(sd_bus_message *m, void *userdata, sd_bus_error *ret_error) {
-        uint32_t ret;
-        int r;
-
-        assert(m);
-
-        if (sd_bus_message_is_method_error(m, NULL)) {
-                const sd_bus_error *e = sd_bus_message_get_error(m);
-
-                if (!sd_bus_error_has_name(e, SD_BUS_ERROR_ACCESS_DENIED)) {
-                        log_debug_errno(sd_bus_error_get_errno(e),
-                                        "Unable to request name, failing connection: %s",
-                                        e->message);
-
-                        bus_enter_closing(sd_bus_message_get_bus(m));
-                        return 1;
-                }
-
-                log_debug_errno(sd_bus_error_get_errno(e),
-                                "Unable to request name, retry after reloading DBus configuration: %s",
-                                e->message);
-
-                /* If systemd-timesyncd.service enables DynamicUser= and dbus.service
-                 * started before the dynamic user is realized, then the DBus policy
-                 * about timesyncd has not been enabled yet. So, let's try to reload
-                 * DBus configuration, and after that request name again. Note that it
-                 * seems that no privileges are necessary to call the following method. */
-
-                r = sd_bus_call_method_async(
-                                sd_bus_message_get_bus(m),
-                                NULL,
-                                "org.freedesktop.DBus",
-                                "/org/freedesktop/DBus",
-                                "org.freedesktop.DBus",
-                                "ReloadConfig",
-                                reload_dbus_handler,
-                                NULL, NULL);
-                if (r < 0) {
-                        log_error_errno(r, "Failed to reload DBus configuration: %m");
-                        bus_enter_closing(sd_bus_message_get_bus(m));
-                }
-
-                return 1;
-        }
-
-        r = sd_bus_message_read(m, "u", &ret);
-        if (r < 0)
-                return r;
-
-        switch (ret) {
-
-        case BUS_NAME_ALREADY_OWNER:
-                log_debug("Already owner of requested service name, ignoring.");
-                return 1;
-
-        case BUS_NAME_IN_QUEUE:
-                log_debug("In queue for requested service name.");
-                return 1;
-
-        case BUS_NAME_PRIMARY_OWNER:
-                log_debug("Successfully acquired requested service name.");
-                return 1;
-
-        case BUS_NAME_EXISTS:
-                log_debug("Requested service name already owned, failing connection.");
-                bus_enter_closing(sd_bus_message_get_bus(m));
-                return 1;
-        }
-
-        log_debug("Unexpected response from RequestName(), failing connection.");
-        bus_enter_closing(sd_bus_message_get_bus(m));
-        return 1;
-}
-
 int manager_connect_bus(Manager *m) {
         int r;
 
@@ -279,7 +185,7 @@ int manager_connect_bus(Manager *m) {
         if (r < 0)
                 return log_error_errno(r, "Failed to add manager object vtable: %m");
 
-        r = sd_bus_request_name_async(m->bus, NULL, "org.freedesktop.timesync1", 0, request_name_handler, NULL);
+        r = bus_request_name_async_may_reload_dbus(m->bus, NULL, "org.freedesktop.timesync1", 0, NULL);
         if (r < 0)
                 return log_error_errno(r, "Failed to request name: %m");
 
index 7950c7e7fbd00e4424930e1e5dd644a891ec8ca8..1e12d058259306dc464ac574c263ff5181f64234 100644 (file)
@@ -14,7 +14,7 @@ const struct ConfigPerfItem* timesyncd_gperf_lookup(const char *key, GPERF_LEN_T
 
 int manager_parse_server_string(Manager *m, ServerType type, const char *string);
 
-int config_parse_servers(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);
+CONFIG_PARSER_PROTOTYPE(config_parse_servers);
 
 int manager_parse_config_file(Manager *m);
 int manager_parse_fallback_string(Manager *m, const char *string);
index 4f639577ad4280dd9a38aed24dff41c4a3cab40a..f76f07e655073b9c1667cda68308517b8eb4d91f 100644 (file)
@@ -804,7 +804,7 @@ int manager_connect(Manager *m) {
         manager_disconnect(m);
 
         m->event_retry = sd_event_source_unref(m->event_retry);
-        if (!ratelimit_test(&m->ratelimit)) {
+        if (!ratelimit_below(&m->ratelimit)) {
                 log_debug("Slowing down attempts to contact servers.");
 
                 r = sd_event_add_time(m->event, &m->event_retry, clock_boottime_or_monotonic(), now(clock_boottime_or_monotonic()) + RETRY_USEC, 0, manager_retry_connect, m);
index bc662991425bc6d9215c9baa67a4b94616e17e51..9a9cfdd8a28f9cc5011a4d655a8409369db8063e 100644 (file)
@@ -60,6 +60,7 @@
 #include "string-table.h"
 #include "string-util.h"
 #include "strv.h"
+#include "terminal-util.h"
 #include "umask-util.h"
 #include "user-util.h"
 #include "util.h"
@@ -149,6 +150,7 @@ typedef enum DirectoryType {
         _DIRECTORY_TYPE_MAX,
 } DirectoryType;
 
+static bool arg_cat_config = false;
 static bool arg_user = false;
 static bool arg_create = false;
 static bool arg_clean = false;
@@ -1305,7 +1307,7 @@ static int item_do(Item *i, int fd, const struct stat *st, fdaction_t action) {
         r = action(i, fd, st);
 
         if (S_ISDIR(st->st_mode)) {
-                char procfs_path[strlen("/proc/self/fd/") + DECIMAL_STR_MAX(int)];
+                char procfs_path[STRLEN("/proc/self/fd/") + DECIMAL_STR_MAX(int)];
                 _cleanup_closedir_ DIR *d = NULL;
                 struct dirent *de;
 
@@ -1502,7 +1504,7 @@ static int create_item(Item *i) {
 
                 if (IN_SET(i->type, CREATE_SUBVOLUME, CREATE_SUBVOLUME_INHERIT_QUOTA, CREATE_SUBVOLUME_NEW_QUOTA)) {
 
-                        if (btrfs_is_subvol(isempty(arg_root) ? "/" : arg_root) <= 0)
+                        if (btrfs_is_subvol(empty_to_root(arg_root)) <= 0)
 
                                 /* Don't create a subvolume unless the
                                  * root directory is one, too. We do
@@ -2113,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;
@@ -2142,9 +2181,7 @@ static int parse_line(const char *fname, unsigned line, const char *buffer, bool
                         /* invalid quoting and such or an unknown specifier */
                         *invalid_config = true;
                 return log_error_errno(r, "[%s:%u] Failed to parse line: %m", fname, line);
-        }
-
-        else if (r < 2) {
+        } else if (r < 2) {
                 *invalid_config = true;
                 log_error("[%s:%u] Syntax error.", fname, line);
                 return -EIO;
@@ -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:
@@ -2441,12 +2482,24 @@ static int parse_line(const char *fname, unsigned line, const char *buffer, bool
         return 0;
 }
 
+static int cat_config(char **config_dirs, char **args) {
+        _cleanup_strv_free_ char **files = NULL;
+        int r;
+
+        r = conf_files_list_with_replacement(arg_root, config_dirs, arg_replace, &files, NULL);
+        if (r < 0)
+                return r;
+
+        return cat_files(NULL, files, 0);
+}
+
 static void help(void) {
         printf("%s [OPTIONS...] [CONFIGURATION FILE...]\n\n"
                "Creates, deletes and cleans up volatile and temporary files and directories.\n\n"
                "  -h --help                 Show this help\n"
                "     --user                 Execute user configuration\n"
                "     --version              Show package version\n"
+               "     --cat-config           Show configuration files\n"
                "     --create               Create marked files/directories\n"
                "     --clean                Clean up marked directories\n"
                "     --remove               Remove marked files/directories\n"
@@ -2462,6 +2515,7 @@ static int parse_argv(int argc, char *argv[]) {
 
         enum {
                 ARG_VERSION = 0x100,
+                ARG_CAT_CONFIG,
                 ARG_USER,
                 ARG_CREATE,
                 ARG_CLEAN,
@@ -2477,6 +2531,7 @@ static int parse_argv(int argc, char *argv[]) {
                 { "help",           no_argument,         NULL, 'h'                },
                 { "user",           no_argument,         NULL, ARG_USER           },
                 { "version",        no_argument,         NULL, ARG_VERSION        },
+                { "cat-config",     no_argument,         NULL, ARG_CAT_CONFIG     },
                 { "create",         no_argument,         NULL, ARG_CREATE         },
                 { "clean",          no_argument,         NULL, ARG_CLEAN          },
                 { "remove",         no_argument,         NULL, ARG_REMOVE         },
@@ -2504,6 +2559,10 @@ static int parse_argv(int argc, char *argv[]) {
                 case ARG_VERSION:
                         return version();
 
+                case ARG_CAT_CONFIG:
+                        arg_cat_config = true;
+                        break;
+
                 case ARG_USER:
                         arg_user = true;
                         break;
@@ -2557,11 +2616,16 @@ static int parse_argv(int argc, char *argv[]) {
                         assert_not_reached("Unhandled option");
                 }
 
-        if (!arg_clean && !arg_create && !arg_remove) {
+        if (!arg_clean && !arg_create && !arg_remove && !arg_cat_config) {
                 log_error("You need to specify at least one of --clean, --create or --remove.");
                 return -EINVAL;
         }
 
+        if (arg_replace && arg_cat_config) {
+                log_error("Option --replace= is not supported with --cat-config");
+                return -EINVAL;
+        }
+
         if (arg_replace && optind >= argc) {
                 log_error("When --replace= is given, some configuration items must be specified");
                 return -EINVAL;
@@ -2677,19 +2741,9 @@ static int read_config_files(char **config_dirs, char **args, bool *invalid_conf
         char **f;
         int r;
 
-        r = conf_files_list_strv(&files, ".conf", arg_root, 0, (const char* const*) config_dirs);
+        r = conf_files_list_with_replacement(arg_root, config_dirs, arg_replace, &files, &p);
         if (r < 0)
-                return log_error_errno(r, "Failed to enumerate tmpfiles.d files: %m");
-
-        if (arg_replace) {
-                r = conf_files_insert(&files, arg_root, config_dirs, arg_replace);
-                if (r < 0)
-                        return log_error_errno(r, "Failed to extend tmpfiles.d file list: %m");
-
-                p = path_join(arg_root, arg_replace, NULL);
-                if (!p)
-                        return log_oom();
-        }
+                return r;
 
         STRV_FOREACH(f, files)
                 if (p && path_equal(*f, p)) {
@@ -2721,20 +2775,6 @@ int main(int argc, char *argv[]) {
         log_parse_environment();
         log_open();
 
-        umask(0022);
-
-        mac_selinux_init();
-
-        items = ordered_hashmap_new(&string_hash_ops);
-        globs = ordered_hashmap_new(&string_hash_ops);
-
-        if (!items || !globs) {
-                r = log_oom();
-                goto finish;
-        }
-
-        r = 0;
-
         if (arg_user) {
                 r = user_config_paths(&config_dirs);
                 if (r < 0) {
@@ -2757,6 +2797,23 @@ int main(int argc, char *argv[]) {
                         log_debug("Looking for configuration files in (higher priority first):\n\t%s", t);
         }
 
+        if (arg_cat_config) {
+                r = cat_config(config_dirs, argv + optind);
+                goto finish;
+        }
+
+        umask(0022);
+
+        mac_selinux_init();
+
+        items = ordered_hashmap_new(&string_hash_ops);
+        globs = ordered_hashmap_new(&string_hash_ops);
+
+        if (!items || !globs) {
+                r = log_oom();
+                goto finish;
+        }
+
         /* If command line arguments are specified along with --replace, read all
          * configuration files and insert the positional arguments at the specified
          * place. Otherwise, if command line arguments are specified, execute just
index a58191d4a74200d9b084b2cf948d8b370aa50012..8fa0627d00529b0bd77c0f9311512552be610c62 100644 (file)
@@ -111,12 +111,29 @@ libudev_basic = static_library(
         c_args : ['-fvisibility=default'])
 
 libudev_static = static_library(
-        'udev',
+        'udev_static',
         'udev.h',
         include_directories : includes,
         link_with : udev_link_with,
         link_whole : libudev_basic)
 
+static_libudev = get_option('static-libudev')
+static_libudev_pic = static_libudev == 'true' or static_libudev == 'pic'
+install_libudev_static = static_library(
+        'udev',
+        basic_sources,
+        shared_sources,
+        libsystemd_sources,
+        libudev_sources,
+        include_directories : includes,
+        build_by_default : static_libudev != 'false',
+        install : static_libudev != 'false',
+        install_dir : rootlibdir,
+        link_depends : libudev_sym,
+        dependencies : libshared_deps + [libmount],
+        c_args : static_libudev_pic ? [] : ['-fno-PIC'],
+        pic : static_libudev_pic)
+
 libudev = shared_library(
         'udev',
         'udev.h', # pick a header file at random to work around old meson bug
index 1d692f1187abe434a9d39385de54e9ce666f8bfd..fa5f41faa5aa0909d1396be5abc5a4c5892cc81e 100644 (file)
@@ -18,6 +18,7 @@
  * Boston, MA  02110-1301  USA
  */
 
+#include <errno.h>
 #include <fcntl.h>
 #include <mtd/mtd-user.h>
 #include <stdio.h>
 #include <sys/types.h>
 #include <unistd.h>
 
+#include "alloc-util.h"
+#include "fd-util.h"
 #include "mtd_probe.h"
 
-int main(int argc, char** argv)
-{
-        int mtd_fd;
-        int error;
+int main(int argc, char** argv) {
+        _cleanup_close_ int mtd_fd = -1;
         mtd_info_t mtd_info;
 
         if (argc != 2) {
                 printf("usage: mtd_probe /dev/mtd[n]\n");
-                return 1;
+                return EXIT_FAILURE;
         }
 
         mtd_fd = open(argv[1], O_RDONLY|O_CLOEXEC);
-        if (mtd_fd == -1) {
-                perror("open");
-                exit(-1);
+        if (mtd_fd < 0) {
+                log_error_errno(errno, "Failed to open: %m");
+                return EXIT_FAILURE;
         }
 
-        error = ioctl(mtd_fd, MEMGETINFO, &mtd_info);
-        if (error == -1) {
-                perror("ioctl");
-                exit(-1);
+        if (ioctl(mtd_fd, MEMGETINFO, &mtd_info) < 0) {
+                log_error_errno(errno, "Failed to issue MEMGETINFO ioctl: %m");
+                return EXIT_FAILURE;
         }
 
-        probe_smart_media(mtd_fd, &mtd_info);
-        return -1;
+        if (probe_smart_media(mtd_fd, &mtd_info) < 0)
+                return EXIT_FAILURE;
+
+        return EXIT_SUCCESS;
 }
index 39841f9b7d643edf03f16ea448090c6a51a44038..20ff862e51d1d229696853313a586a6df2ce4258 100644 (file)
@@ -49,4 +49,4 @@ struct sm_oob {
 #define SM_SMALL_PAGE                 256
 #define SM_SMALL_OOB_SIZE        8
 
-void probe_smart_media(int mtd_fd, mtd_info_t *info);
+int probe_smart_media(int mtd_fd, mtd_info_t *info);
index c058d83c2ed4da1def5fae5fc3a63f301300dfa0..da937a399dc6183944436c3cca695c1aa286ad88 100644 (file)
@@ -18,6 +18,7 @@
  * Boston, MA  02110-1301  USA
  */
 
+#include <errno.h>
 #include <fcntl.h>
 #include <mtd/mtd-user.h>
 #include <stdint.h>
@@ -35,7 +36,7 @@ static const uint8_t cis_signature[] = {
         0x01, 0x03, 0xD9, 0x01, 0xFF, 0x18, 0x02, 0xDF, 0x01, 0x20
 };
 
-void probe_smart_media(int mtd_fd, mtd_info_t* info) {
+int probe_smart_media(int mtd_fd, mtd_info_t* info) {
         int sector_size;
         int block_size;
         int size_in_megs;
@@ -46,17 +47,21 @@ void probe_smart_media(int mtd_fd, mtd_info_t* info) {
 
         cis_buffer = malloc(SM_SECTOR_SIZE);
         if (!cis_buffer)
-                return;
+                return log_oom();
 
-        if (info->type != MTD_NANDFLASH)
-                goto exit;
+        if (info->type != MTD_NANDFLASH) {
+                log_debug("Not marked MTD_NANDFLASH.");
+                return -EINVAL;
+        }
 
         sector_size = info->writesize;
         block_size = info->erasesize;
         size_in_megs = info->size / (1024 * 1024);
 
-        if (!IN_SET(sector_size, SM_SECTOR_SIZE, SM_SMALL_PAGE))
-                goto exit;
+        if (!IN_SET(sector_size, SM_SECTOR_SIZE, SM_SMALL_PAGE)) {
+                log_debug("Unexpected sector size: %i", sector_size);
+                return -EINVAL;
+        }
 
         switch(size_in_megs) {
         case 1:
@@ -71,26 +76,26 @@ void probe_smart_media(int mtd_fd, mtd_info_t* info) {
                 break;
         }
 
-        for (offset = 0 ; offset < block_size * spare_count ;
-                                                offset += sector_size) {
-                lseek(mtd_fd, SEEK_SET, offset);
+        for (offset = 0; offset < block_size * spare_count; offset += sector_size) {
+                (void) lseek(mtd_fd, SEEK_SET, offset);
+
                 if (read(mtd_fd, cis_buffer, SM_SECTOR_SIZE) == SM_SECTOR_SIZE) {
                         cis_found = 1;
                         break;
                 }
         }
 
-        if (!cis_found)
-                goto exit;
+        if (!cis_found) {
+                log_debug("CIS not found");
+                return -EINVAL;
+        }
 
         if (memcmp(cis_buffer, cis_signature, sizeof(cis_signature)) != 0 &&
-                (memcmp(cis_buffer + SM_SMALL_PAGE, cis_signature,
-                        sizeof(cis_signature)) != 0))
-                goto exit;
+            memcmp(cis_buffer + SM_SMALL_PAGE, cis_signature, sizeof(cis_signature)) != 0) {
+                log_debug("CIS signature didn't match");
+                return -EINVAL;
+        }
 
         printf("MTD_FTL=smartmedia\n");
-        exit(EXIT_SUCCESS);
-
-exit:
-        return;
+        return 0;
 }
index ccea64b5735c56ff4ffa51fd906411a715ba8387..37525ce841b2406f76afa575b349241bc3e1cc52 100644 (file)
@@ -568,3 +568,105 @@ int ethtool_set_glinksettings(int *fd, const char *ifname, struct link_config *l
 
         return r;
 }
+
+int config_parse_channel(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) {
+        link_config *config = data;
+        uint32_t k;
+        int r;
+
+        assert(filename);
+        assert(section);
+        assert(lvalue);
+        assert(rvalue);
+        assert(data);
+
+        r = safe_atou32(rvalue, &k);
+        if (r < 0) {
+                log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse channel value, ignoring: %s", rvalue);
+                return 0;
+        }
+
+        if (k < 1) {
+                log_syntax(unit, LOG_ERR, filename, line, -EINVAL, "Invalid %s value, ignoring: %s", lvalue, rvalue);
+                return 0;
+        }
+
+        if (streq(lvalue, "RxChannels")) {
+                config->channels.rx_count = k;
+                config->channels.rx_count_set = true;
+        } else if (streq(lvalue, "TxChannels")) {
+                config->channels.tx_count = k;
+                config->channels.tx_count_set = true;
+        } else if (streq(lvalue, "OtherChannels")) {
+                config->channels.other_count = k;
+                config->channels.other_count_set = true;
+        } else if (streq(lvalue, "CombinedChannels")) {
+                config->channels.combined_count = k;
+                config->channels.combined_count_set = true;
+        }
+
+        return 0;
+}
+
+int ethtool_set_channels(int *fd, const char *ifname, netdev_channels *channels) {
+        struct ethtool_channels ecmd = {
+                .cmd = ETHTOOL_GCHANNELS
+        };
+        struct ifreq ifr = {
+                .ifr_data = (void*) &ecmd
+        };
+
+        bool need_update = false;
+        int r;
+
+        if (*fd < 0) {
+                r = ethtool_connect(fd);
+                if (r < 0)
+                        return log_warning_errno(r, "link_config: could not connect to ethtool: %m");
+        }
+
+        strscpy(ifr.ifr_name, IFNAMSIZ, ifname);
+
+        r = ioctl(*fd, SIOCETHTOOL, &ifr);
+        if (r < 0)
+                return -errno;
+
+        if (channels->rx_count_set && ecmd.rx_count != channels->rx_count) {
+                ecmd.rx_count = channels->rx_count;
+                need_update = true;
+        }
+
+        if (channels->tx_count_set && ecmd.tx_count != channels->tx_count) {
+                ecmd.tx_count = channels->tx_count;
+                need_update = true;
+        }
+
+        if (channels->other_count_set && ecmd.other_count != channels->other_count) {
+                ecmd.other_count = channels->other_count;
+                need_update = true;
+        }
+
+        if (channels->combined_count_set && ecmd.combined_count != channels->combined_count) {
+                ecmd.combined_count = channels->combined_count;
+                need_update = true;
+        }
+
+        if (need_update) {
+                ecmd.cmd = ETHTOOL_SCHANNELS;
+
+                r = ioctl(*fd, SIOCETHTOOL, &ifr);
+                if (r < 0)
+                        return -errno;
+        }
+
+        return 0;
+}
index 1db07dec53ae7350ff76e8bbf05efa4bbf302896..da2a2458f0ca6abce4d38c244aa5ab73e32f3c3d 100644 (file)
@@ -72,6 +72,18 @@ struct ethtool_link_usettings {
         } link_modes;
 };
 
+typedef struct netdev_channels {
+        uint32_t rx_count;
+        uint32_t tx_count;
+        uint32_t other_count;
+        uint32_t combined_count;
+
+        bool rx_count_set;
+        bool tx_count_set;
+        bool other_count_set;
+        bool combined_count_set;
+} netdev_channels;
+
 int ethtool_connect(int *ret);
 
 int ethtool_get_driver(int *fd, const char *ifname, char **ret);
@@ -79,6 +91,7 @@ int ethtool_set_speed(int *fd, const char *ifname, unsigned int speed, Duplex du
 int ethtool_set_wol(int *fd, const char *ifname, WakeOnLan wol);
 int ethtool_set_features(int *fd, const char *ifname, NetDevFeature *features);
 int ethtool_set_glinksettings(int *fd, const char *ifname, struct link_config *link);
+int ethtool_set_channels(int *fd, const char *ifname, netdev_channels *channels);
 
 const char *duplex_to_string(Duplex d) _const_;
 Duplex duplex_from_string(const char *d) _pure_;
@@ -92,3 +105,4 @@ NetDevPort port_from_string(const char *port) _pure_;
 int config_parse_duplex(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_wol(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_port(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_channel(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 8bfa998dacf6a70d0c0b08074886f7242b3aac9a..5640fa051376820cc3be5c2761511bf1fe39dc14 100644 (file)
@@ -4,9 +4,9 @@ _Pragma("GCC diagnostic ignored \"-Wimplicit-fallthrough\"")
 #endif
 #include <stddef.h>
 #include "conf-parser.h"
-#include "network-internal.h"
-#include "link-config.h"
 #include "ethtool-util.h"
+#include "link-config.h"
+#include "network-internal.h"
 %}
 struct ConfigPerfItem;
 %null_strings
@@ -19,7 +19,7 @@ struct ConfigPerfItem;
 %struct-type
 %includes
 %%
-Match.MACAddress,                config_parse_hwaddr       0,                             offsetof(link_config, match_mac)
+Match.MACAddress,                config_parse_hwaddrs,       0,                             offsetof(link_config, match_mac)
 Match.OriginalName,              config_parse_ifnames,       0,                             offsetof(link_config, match_name)
 Match.Path,                      config_parse_strv,          0,                             offsetof(link_config, match_path)
 Match.Driver,                    config_parse_strv,          0,                             offsetof(link_config, match_driver)
@@ -47,3 +47,7 @@ Link.TCP6SegmentationOffload,    config_parse_tristate,      0,
 Link.UDPSegmentationOffload,     config_parse_warn_compat,   DISABLED_LEGACY,               0
 Link.GenericReceiveOffload,      config_parse_tristate,      0,                             offsetof(link_config, features[NET_DEV_FEAT_GRO])
 Link.LargeReceiveOffload,        config_parse_tristate,      0,                             offsetof(link_config, features[NET_DEV_FEAT_LRO])
+Link.RxChannels,                 config_parse_channel,       0,                             0
+Link.TxChannels,                 config_parse_channel,       0,                             0
+Link.OtherChannels,              config_parse_channel,       0,                             0
+Link.CombinedChannels,           config_parse_channel,       0,                             0
index c4fab4e63b1f940d17e2951affc54ef8c443231f..2f7aa2f8d9d59dda8b06d06b1596a8d4578d4d05 100644 (file)
@@ -57,7 +57,7 @@ static void link_config_free(link_config *link) {
 
         free(link->filename);
 
-        free(link->match_mac);
+        set_free_free(link->match_mac);
         strv_free(link->match_path);
         strv_free(link->match_driver);
         strv_free(link->match_type);
@@ -393,6 +393,12 @@ int link_config_apply(link_config_ctx *ctx, link_config *config,
         if (r < 0)
                 log_warning_errno(r, "Could not set offload features of %s: %m", old_name);
 
+        if (config->channels.rx_count_set || config->channels.tx_count_set || config->channels.other_count_set || config->channels.combined_count_set) {
+                r = ethtool_set_channels(&ctx->ethtool_fd, old_name, &config->channels);
+                if (r < 0)
+                        log_warning_errno(r, "Could not set channels of %s: %m", old_name);
+        }
+
         ifindex = udev_device_get_ifindex(device);
         if (ifindex <= 0) {
                 log_warning("Could not find ifindex");
index 9f411328105573a851426e654642ef8d05c866a9..cbc532e340c4c36d758258812875c0bfc6025fb9 100644 (file)
@@ -12,6 +12,7 @@
 #include "condition.h"
 #include "ethtool-util.h"
 #include "list.h"
+#include "set.h"
 
 typedef struct link_config_ctx link_config_ctx;
 typedef struct link_config link_config;
@@ -38,7 +39,7 @@ typedef enum NamePolicy {
 struct link_config {
         char *filename;
 
-        struct ether_addr *match_mac;
+        Set *match_mac;
         char **match_path;
         char **match_driver;
         char **match_type;
@@ -62,6 +63,7 @@ struct link_config {
         WakeOnLan wol;
         NetDevPort port;
         NetDevFeature features[_NET_DEV_FEAT_MAX];
+        netdev_channels channels;
 
         LIST_FIELDS(link_config, links);
 };
index c946131fb754f1db81cceb2fad2b0e785693a46f..646c8507f70ba88c131d90b6b2ca9972b5e835b6 100644 (file)
@@ -703,7 +703,8 @@ out:
         if (trie) {
                 if (trie->root)
                         trie_node_cleanup(trie->root);
-                strbuf_cleanup(trie->strings);
+                if (trie->strings)
+                        strbuf_cleanup(trie->strings);
                 free(trie);
         }
         return rc;
index cc4b5d26347db7ff6e43eb9f4bbf1573e7295168..eba84e1d55c1d05495b73a6c27ab5cfa2b470753 100644 (file)
@@ -28,7 +28,7 @@ foreach file : m4_files
                 'sysusers.d_' + file,
                 input : file + '.m4',
                 output: file,
-                command : [m4, '-P'] + m4_defines + ['@INPUT@'],
+                command : [meson_apply_m4, config_h, '@INPUT@'],
                 capture : true,
                 install : enable_sysusers,
                 install_dir : sysusersdir)
index 82e23ca5a870da0e3fc0170b264ddcac9aa24155..2315b56e3fcfcfbf0d914a585fedfd55b93f1e20 100644 (file)
@@ -6,12 +6,6 @@
 #  (at your option) any later version.
 
 g systemd-journal   - -
-m4_ifdef(`ENABLE_NETWORKD',
-u systemd-network   - "systemd Network Management"
-)m4_dnl
-m4_ifdef(`ENABLE_RESOLVE',
-u systemd-resolve   - "systemd Resolver"
-)m4_dnl
 m4_ifdef(`ENABLE_COREDUMP',
 u systemd-coredump  - "systemd Core Dumper"
 )m4_dnl
index 81b4d2ceb5f839d0fe3849af3ff04ab5854fe76a..a51b3ebde9a403d446ba7461414b9b5fded44e81 100755 (executable)
@@ -205,6 +205,29 @@ Priority=0
         subprocess.check_call(['systemctl', 'restart', 'systemd-networkd'])
         self.assertEqual(self.read_attr('port2', 'brport/priority'), '0')
 
+    def test_bridge_port_property(self):
+        """Test the "[Bridge]" section keys"""
+        self.assertEqual(self.read_attr('port2', 'brport/priority'), '32')
+        self.write_network_dropin('port2.network', 'property', '''\
+[Bridge]
+UnicastFlood=true
+HairPin=true
+UseBPDU=true
+FastLeave=true
+AllowPortToBeRoot=true
+Cost=555
+Priority=23
+''')
+        subprocess.check_call(['systemctl', 'restart', 'systemd-networkd'])
+
+        self.assertEqual(self.read_attr('port2', 'brport/priority'), '23')
+        self.assertEqual(self.read_attr('port2', 'brport/hairpin_mode'), '1')
+        self.assertEqual(self.read_attr('port2', 'brport/path_cost'), '555')
+        self.assertEqual(self.read_attr('port2', 'brport/multicast_fast_leave'), '1')
+        self.assertEqual(self.read_attr('port2', 'brport/unicast_flood'), '1')
+        self.assertEqual(self.read_attr('port2', 'brport/bpdu_guard'), '1')
+        self.assertEqual(self.read_attr('port2', 'brport/root_block'), '1')
+
 class ClientTestBase(NetworkdTestingUtilities):
     """Provide common methods for testing networkd against servers."""
 
index 5a61228c9f715fe812a30da92fa954e6a456ceeb..edb0be7ef80832f56f7b7fc0802b95ac204ba6d6 100644 (file)
@@ -1,5 +1,5 @@
 [Unit]
-Description=Test DynamicUser= migrate StateDirectory= (preparation)
+Description=Test DynamicUser= migrate StateDirectory=
 
 [Service]
 ExecStart=test -w /var/lib/test-dynamicuser-migrate
index cd4747aa204b7395058639ca065ce0e23f119f22..9bcb133aecce4b25901ed0a78947d599c4a42a98 100644 (file)
@@ -2,6 +2,6 @@
 Description=Test for EnvironmentFile
 
 [Service]
-ExecStart=/bin/sh -x -c 'test "$$VAR1" = "word1 word2" && test "$$VAR2" = word3 && test "$$VAR3" = "\\$$word 5 6" && test "$$VAR4" = "new\nline"'
+ExecStart=/bin/sh -x -c 'test "$$VAR1" = "word1 word2" && test "$$VAR2" = word3 && test "$$VAR3" = "\\$$word 5 6" && test "$$VAR4" = "new\nline" && test "$$VAR5" = passwordwithbackslashes'
 Type=oneshot
 EnvironmentFile=/tmp/test-exec_environmentfile.conf
index 4a82206a2c6f0d4c29a2007e6de9597662f8a597..d257e48cda4d25203bcd1f4ac29ba2dcf6d7d335 100644 (file)
@@ -2,6 +2,6 @@
 Description=Test for PassEnvironment with variables absent from the execution environment
 
 [Service]
-ExecStart=/bin/sh -x -c 'test "$${VAR1-unset}" = "unset" && test "$${VAR2-unset}" = "unset" && test "$${VAR3-unset}" = "unset" && test "$${VAR4-unset}" = "unset"'
+ExecStart=/bin/sh -x -c 'test "$${VAR1-unset}" = "unset" && test "$${VAR2-unset}" = "unset" && test "$${VAR3-unset}" = "unset" && test "$${VAR4-unset}" = "unset" && test "$${VAR5-unset}" = "unset"'
 Type=oneshot
-PassEnvironment=VAR1 VAR2 VAR3 VAR4
+PassEnvironment=VAR1 VAR2 VAR3 VAR4 VAR5
index 8716cdf6bbfcbf6fb035a16916db0674dda409ff..291259a34716c3be1e3575d4b5bfe9708fddc6f2 100644 (file)
@@ -2,7 +2,7 @@
 Description=Test for PassEnvironment and erasing the variable list
 
 [Service]
-ExecStart=/bin/sh -x -c 'test "$${VAR1-unset}" = "unset" && test "$${VAR2-unset}" = "unset" && test "$${VAR3-unset}" = "unset" && test "$${VAR4-unset}" = "unset"'
+ExecStart=/bin/sh -x -c 'test "$${VAR1-unset}" = "unset" && test "$${VAR2-unset}" = "unset" && test "$${VAR3-unset}" = "unset" && test "$${VAR4-unset}" = "unset" && test "$${VAR5-unset}" = "unset"'
 Type=oneshot
-PassEnvironment=VAR1 VAR2 VAR3 VAR4
+PassEnvironment=VAR1 VAR2 VAR3 VAR4 VAR5
 PassEnvironment=
index d518d7d8a58a0d6f83244d8108f74cbba91a2c62..e88699802f243ef82ba6abc7e9e906e3a76d28fa 100644 (file)
@@ -2,8 +2,9 @@
 Description=Test for PassEnvironment with a variable name repeated
 
 [Service]
-ExecStart=/bin/sh -x -c 'test "$$VAR1" = "word1 word2" && test "$$VAR2" = word3 && test "$$VAR3" = "\\$$word 5 6" && test "$$VAR4" = "new\nline"'
+ExecStart=/bin/sh -x -c 'test "$$VAR1" = "word1 word2" && test "$$VAR2" = word3 && test "$$VAR3" = "\\$$word 5 6" && test "$$VAR4" = "new\nline" && test "$$VAR5" = passwordwithbackslashes'
 Type=oneshot
 PassEnvironment=VAR1 VAR2
 PassEnvironment=VAR1 VAR3
 PassEnvironment=VAR1 VAR4
+PassEnvironment=VAR1 VAR5
index cca44ebf4ae1f5faa66082477ea3b5e53917b8d5..05c1bdfe882d88a8ae09fa154a6986f82a7db022 100644 (file)
@@ -2,6 +2,6 @@
 Description=Test for PassEnvironment
 
 [Service]
-ExecStart=/bin/sh -x -c 'test "$$VAR1" = "word1 word2" && test "$$VAR2" = word3 && test "$$VAR3" = "\\$$word 5 6" && test "$$VAR4" = "new\nline"'
+ExecStart=/bin/sh -x -c 'test "$$VAR1" = "word1 word2" && test "$$VAR2" = word3 && test "$$VAR3" = "\\$$word 5 6" && test "$$VAR4" = "new\nline" && test "$$VAR5" = passwordwithbackslashes'
 Type=oneshot
-PassEnvironment=VAR1 VAR2 VAR3 VAR4
+PassEnvironment=VAR1 VAR2 VAR3 VAR4 VAR5
index a7a7d0a1d7aa0d909beef0f513acfa8cb8a22fd9..20b1e0d0bc91f18f3040fcaa93fddf0371bd2297 100644 (file)
@@ -37,7 +37,7 @@ foreach pair : m4_files
                         'tmpfiles.d_' + pair[0],
                          input : pair[0] + '.m4',
                          output: pair[0],
-                         command : [m4, '-P'] + m4_defines + ['@INPUT@'],
+                         command : [meson_apply_m4, config_h, '@INPUT@'],
                          capture : true,
                          install : true,
                          install_dir : tmpfilesdir)
index 76e3829ab21232a9e62ca77f7cd38edf78b0dc88..222a42422d0621607614c4351e051e0bb0ab135c 100644 (file)
@@ -17,9 +17,9 @@ d /run/systemd/users 0755 root root -
 d /run/systemd/machines 0755 root root -
 d /run/systemd/shutdown 0755 root root -
 m4_ifdef(`ENABLE_NETWORKD',
-d /run/systemd/netif 0755 systemd-network systemd-network -
-d /run/systemd/netif/links 0755 systemd-network systemd-network -
-d /run/systemd/netif/leases 0755 systemd-network systemd-network -
+d /run/systemd/netif 0755 root root -
+d /run/systemd/netif/links 0755 root root -
+d /run/systemd/netif/leases 0755 root root -
 )m4_dnl
 
 d /run/log 0755 root root -
@@ -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 -
index c41811483cbb91fae5510ef22270fdd230980fe3..6e7e4cb6996259e4c65a031cbed14e5e5e0e56e3 100755 (executable)
@@ -10,7 +10,7 @@ case "$1" in
                         DIR="$2"
                 fi
 
-                find $DIR -type f \( -name '*.c' -o -name '*.xml' \) -exec $0 diff \{\} \;
+                find $DIR -type f \( -name '*.[ch]' -o -name '*.xml' \) -exec $0 diff \{\} \;
                 ;;
 
         recpatch)
@@ -20,7 +20,7 @@ case "$1" in
                         DIR="$2"
                 fi
 
-                find $DIR -type f \( -name '*.c' -o -name '*.xml' \) -exec $0 patch \{\} \;
+                find $DIR -type f \( -name '*.[ch]' -o -name '*.xml' \) -exec $0 patch \{\} \;
                 ;;
 
         diff)
diff --git a/tools/find-tabs.sh b/tools/find-tabs.sh
new file mode 100755 (executable)
index 0000000..611931c
--- /dev/null
@@ -0,0 +1,40 @@
+#!/bin/sh
+# SPDX-License-Identifier: LGPL-2.1+
+
+case "$1" in
+
+        recdiff)
+                if [ "$2" = "" ] ; then
+                        DIR="$PWD/.."
+                else
+                        DIR="$2"
+                fi
+
+                find $DIR -type f \( -name '*.[ch]' -o -name '*.xml' \) -exec $0 diff \{\} \;
+                ;;
+
+        recpatch)
+                if [ "$2" = "" ] ; then
+                        DIR="$PWD/.."
+                else
+                        DIR="$2"
+                fi
+
+                find $DIR -type f \( -name '*.[ch]' -o -name '*.xml' \) -exec $0 patch \{\} \;
+                ;;
+
+        diff)
+                T=`mktemp`
+                sed 's/\t/        /g' < "$2" > "$T"
+                diff -u "$2" "$T"
+                rm -f "$T"
+                ;;
+
+        patch)
+                sed -i 's/\t/        /g' "$2"
+                ;;
+
+        *)
+                echo "Expected recdiff|recpatch|diff|patch as verb." >&2
+                ;;
+esac
diff --git a/tools/meson-apply-m4.sh b/tools/meson-apply-m4.sh
new file mode 100755 (executable)
index 0000000..6abe177
--- /dev/null
@@ -0,0 +1,24 @@
+#!/bin/sh
+set -eu
+
+CONFIG=$1
+TARGET=$2
+
+if [ $# -ne 2 ]; then
+        echo 'Invalid number of arguments.'
+        exit 1
+fi
+
+if [ ! -f $CONFIG ]; then
+        echo "$CONFIG not found."
+        exit 2
+fi
+
+if [ ! -f $TARGET ]; then
+        echo "$TARGET not found."
+        exit 3
+fi
+
+DEFINES=$(awk '$1 == "#define" && $3 == "1" { printf "-D%s ", $2 }' $CONFIG)
+
+m4 -P $DEFINES $TARGET
index 3682e5b0c64455760ee46c4d4354b4bd383ac23e..7cc7df5106db67ce49c3633eb4b32e57b9d8cd38 100755 (executable)
@@ -46,8 +46,8 @@ df=$build/dns-fuzzing
 git clone --depth 1 https://github.com/CZ-NIC/dns-fuzzing $df
 zip -jqr $OUT/fuzz-dns-packet_seed_corpus.zip $df/packet
 
-mkdir -p $OUT/src/shared
-mv $build/src/shared/libsystemd-shared-*.so $OUT/src/shared
+# install the private shared library without executable permissions
+install -Dt $OUT/src/shared/ -m 0644 $build/src/shared/libsystemd-shared-*.so
 
 find $build -maxdepth 1 -type f -executable -name "fuzz-*" -exec mv {} $OUT \;
 cp src/fuzz/*.options $OUT
index f2dbae4b384c92cf4f2ce8b36d9b2217ce1a02b8..9a255f1e9dce7eb12e37c2f0099feff89604cd3e 100644 (file)
@@ -1,3 +1,4 @@
 dnf-plugins-core
 meson
 ninja-build
+ccache
index fed2f107534816a293e8f7d792b1ba50a3a7672d..799fc5d5673b05ac93f8784b92ff0b24e7599068 100644 (file)
@@ -272,7 +272,7 @@ foreach tuple : m4_units
                 file,
                 input : input,
                 output: file,
-                command : [m4, '-P'] + m4_defines + ['@INPUT@'],
+                command : [meson_apply_m4, config_h, '@INPUT@'],
                 capture : true,
                 install : install,
                 install_dir : systemunitdir)
index 63ee735415151a68846e4a5601ae3f610e59b088..adb219a01d4a1a4e668f9490c25ebce5731dbe28 100644 (file)
@@ -13,7 +13,7 @@ Documentation=man:systemd-networkd.service(8)
 ConditionCapability=CAP_NET_ADMIN
 DefaultDependencies=no
 # systemd-udevd.service can be dropped once tuntap is moved to netlink
-After=systemd-udevd.service network-pre.target systemd-sysusers.service systemd-sysctl.service
+After=systemd-udevd.service network-pre.target systemd-sysctl.service
 Before=network.target multi-user.target shutdown.target
 Conflicts=shutdown.target
 Wants=network.target
@@ -25,14 +25,15 @@ RestartSec=0
 ExecStart=!!@rootlibexecdir@/systemd-networkd
 WatchdogSec=3min
 User=systemd-network
+DynamicUser=yes
 CapabilityBoundingSet=CAP_NET_ADMIN CAP_NET_BIND_SERVICE CAP_NET_BROADCAST CAP_NET_RAW
 AmbientCapabilities=CAP_NET_ADMIN CAP_NET_BIND_SERVICE CAP_NET_BROADCAST CAP_NET_RAW
-ProtectSystem=strict
 ProtectHome=yes
 ProtectControlGroups=yes
 ProtectKernelModules=yes
 MemoryDenyWriteExecute=yes
 RestrictRealtime=yes
+RestrictNamespaces=yes
 RestrictAddressFamilies=AF_UNIX AF_NETLINK AF_INET AF_INET6 AF_PACKET
 SystemCallFilter=~@clock @cpu-emulation @debug @keyring @module @mount @obsolete @raw-io @reboot @swap
 SystemCallArchitectures=native
index c4c7f1feef9a5a9e2cd89c0b9b2ae1c58929d92d..7b92735f19b0847e2d2bdb196a06f8ae1b9e6118 100644 (file)
@@ -14,7 +14,7 @@ Documentation=https://www.freedesktop.org/wiki/Software/systemd/resolved
 Documentation=https://www.freedesktop.org/wiki/Software/systemd/writing-network-configuration-managers
 Documentation=https://www.freedesktop.org/wiki/Software/systemd/writing-resolver-clients
 DefaultDependencies=no
-After=systemd-sysusers.service systemd-networkd.service
+After=systemd-networkd.service
 Before=network.target nss-lookup.target shutdown.target
 Conflicts=shutdown.target
 Wants=nss-lookup.target
@@ -26,17 +26,17 @@ RestartSec=0
 ExecStart=!!@rootlibexecdir@/systemd-resolved
 WatchdogSec=3min
 User=systemd-resolve
+DynamicUser=yes
 CapabilityBoundingSet=CAP_SETPCAP CAP_NET_RAW CAP_NET_BIND_SERVICE
 AmbientCapabilities=CAP_SETPCAP CAP_NET_RAW CAP_NET_BIND_SERVICE
-PrivateTmp=yes
 PrivateDevices=yes
-ProtectSystem=strict
 ProtectHome=yes
 ProtectControlGroups=yes
 ProtectKernelTunables=yes
 ProtectKernelModules=yes
 MemoryDenyWriteExecute=yes
 RestrictRealtime=yes
+RestrictNamespaces=yes
 RestrictAddressFamilies=AF_UNIX AF_NETLINK AF_INET AF_INET6
 SystemCallFilter=~@clock @cpu-emulation @debug @keyring @module @mount @obsolete @raw-io @reboot @swap
 SystemCallArchitectures=native
index 913dac773a24856947d778209be6450f9a9e2339..6bfe28627b2200b4f15039dd7565fb19c5c689df 100644 (file)
@@ -13,7 +13,7 @@ Documentation=man:systemd-timesyncd.service(8)
 ConditionCapability=CAP_SYS_TIME
 ConditionVirtualization=!container
 DefaultDependencies=no
-After=systemd-remount-fs.service systemd-sysusers.service
+After=systemd-remount-fs.service
 Before=time-sync.target sysinit.target shutdown.target
 Conflicts=shutdown.target
 Wants=time-sync.target