]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
Merge pull request #18567 from Werkov/mkosi-opensuse-v9+
authorLuca Boccassi <luca.boccassi@microsoft.com>
Wed, 4 Aug 2021 10:35:13 +0000 (11:35 +0100)
committerGitHub <noreply@github.com>
Wed, 4 Aug 2021 10:35:13 +0000 (11:35 +0100)
CI for openSUSE Tumbleweed

463 files changed:
.lgtm.yml
.packit.yml
README
TODO
docs/BOOT_LOADER_INTERFACE.md
docs/BOOT_LOADER_SPECIFICATION.md
docs/DISCOVERABLE_PARTITIONS.md
docs/var-log/README.logs [moved from docs/var-log/README with 100% similarity]
docs/var-log/meson.build
hwdb.d/60-keyboard.hwdb
hwdb.d/60-sensor.hwdb
hwdb.d/meson.build
man/bootctl.xml
man/coredump.conf.xml
man/coredumpctl.xml
man/dnssec-trust-anchors.d.xml
man/meson.build
man/nss-myhostname.xml
man/nss-resolve.xml
man/nss-systemd.xml
man/os-release.xml
man/pam_systemd.xml
man/repart.d.xml
man/sd_bus_set_property.xml
man/systemctl.xml
man/systemd-boot.xml
man/systemd-cryptenroll.xml
man/systemd-firstboot.xml
man/systemd-gpt-auto-generator.xml
man/systemd-machine-id-setup.xml
man/systemd-nspawn.xml
man/systemd-portabled.service.xml
man/systemd-resolved.service.xml
man/systemd-sysext.xml
man/systemd-system.conf.xml
man/systemd-userdbd.service.xml
man/systemd-veritysetup@.service.xml
man/systemd.exec.xml
man/systemd.link.xml
man/systemd.netdev.xml
man/systemd.network.xml
man/systemd.nspawn.xml
man/systemd.preset.xml
man/systemd.service.xml
man/systemd.unit.xml
man/systemd.xml
man/tmpfiles.d.xml
man/userdbctl.xml
meson.build
meson_options.txt
network/meson.build
presets/90-systemd.preset
shell-completion/bash/meson.build
shell-completion/zsh/_systemd-run
shell-completion/zsh/meson.build
src/ac-power/ac-power.c
src/activate/activate.c
src/analyze/analyze-security.c
src/analyze/analyze.c
src/ask-password/ask-password.c
src/backlight/backlight.c
src/basic/alloc-util.h
src/basic/architecture.c
src/basic/efivars.c
src/basic/escape.c
src/basic/escape.h
src/basic/ether-addr-util.h
src/basic/fd-util.c
src/basic/fd-util.h
src/basic/fileio.h
src/basic/format-util.h
src/basic/hashmap.c
src/basic/hexdecoct.c
src/basic/in-addr-util.c
src/basic/locale-util.c
src/basic/locale-util.h
src/basic/log.c
src/basic/log.h
src/basic/macro.h
src/basic/parse-util.c
src/basic/path-lookup.c
src/basic/process-util.c
src/basic/process-util.h
src/basic/rlimit-util.c
src/basic/signal-util.c
src/basic/socket-util.h
src/basic/stdio-util.h
src/basic/strv.h
src/basic/time-util.c
src/basic/time-util.h
src/basic/unit-name.c
src/binfmt/binfmt.c
src/boot/bless-boot.c
src/boot/boot-check-no-failures.c
src/boot/bootctl.c
src/boot/efi/meson.build
src/busctl/busctl-introspect.c
src/busctl/busctl.c
src/cgls/cgls.c
src/cgtop/cgtop.c
src/core/automount.c
src/core/cgroup.c
src/core/dbus-cgroup.c
src/core/dbus-manager.c
src/core/dbus-socket.c
src/core/dbus-timer.c
src/core/dbus-util.c
src/core/dynamic-user.c
src/core/emergency-action.c
src/core/execute.c
src/core/job.c
src/core/load-fragment.c
src/core/main.c
src/core/manager-dump.c
src/core/manager-serialize.c [new file with mode: 0644]
src/core/manager-serialize.h [new file with mode: 0644]
src/core/manager.c
src/core/manager.h
src/core/meson.build
src/core/mount.c
src/core/namespace.c
src/core/path.c
src/core/scope.c
src/core/selinux-setup.c
src/core/service.c
src/core/socket.c
src/core/swap.c
src/core/timer.c
src/core/unit-serialize.c
src/core/unit.c
src/core/unit.h
src/coredump/coredumpctl.c
src/coredump/stacktrace.c
src/creds/creds.c
src/cryptenroll/cryptenroll-tpm2.c
src/cryptenroll/cryptenroll-wipe.c
src/cryptenroll/cryptenroll.c
src/cryptsetup/cryptsetup-tokens/cryptsetup-token-systemd-tpm2.c [new file with mode: 0644]
src/cryptsetup/cryptsetup-tokens/cryptsetup-token-util.c [new file with mode: 0644]
src/cryptsetup/cryptsetup-tokens/cryptsetup-token-util.h [new file with mode: 0644]
src/cryptsetup/cryptsetup-tokens/cryptsetup-token.h [new file with mode: 0644]
src/cryptsetup/cryptsetup-tokens/cryptsetup-token.sym [new file with mode: 0644]
src/cryptsetup/cryptsetup-tokens/luks2-tpm2.c [new file with mode: 0644]
src/cryptsetup/cryptsetup-tokens/luks2-tpm2.h [new file with mode: 0644]
src/cryptsetup/cryptsetup-tokens/meson.build [new file with mode: 0644]
src/cryptsetup/cryptsetup-tpm2.c
src/cryptsetup/cryptsetup-tpm2.h
src/cryptsetup/cryptsetup.c
src/delta/delta.c
src/detect-virt/detect-virt.c
src/dissect/dissect.c
src/escape/escape.c
src/firstboot/firstboot.c
src/fstab-generator/fstab-generator.c
src/fundamental/macro-fundamental.h
src/fundamental/meson.build
src/home/homectl.c
src/home/homed-home.c
src/home/homed-manager.c
src/home/homework-directory.c
src/home/homework-luks.c
src/home/homework.c
src/home/pam_systemd_home.c
src/home/user-record-util.c
src/hostname/hostnamectl.c
src/hwdb/hwdb.c
src/id128/id128.c
src/import/export.c
src/import/import-compress.c
src/import/import-fs.c
src/import/import.c
src/import/importd.c
src/import/pull-common.c
src/import/pull-job.c
src/import/pull-raw.c
src/import/pull-tar.c
src/import/pull.c
src/journal-remote/journal-gatewayd.c
src/journal-remote/journal-remote-main.c
src/journal-remote/journal-remote.c
src/journal-remote/journal-upload-journal.c
src/journal-remote/journal-upload.c
src/journal-remote/log-generator.py
src/journal-remote/meson.build
src/journal/cat.c
src/journal/journalctl.c
src/journal/journald-server.c
src/journal/journald-stream.c
src/kernel-install/meson.build
src/libsystemd-network/sd-dhcp-client.c
src/libsystemd-network/sd-dhcp6-client.c
src/libsystemd-network/sd-ipv4acd.c
src/libsystemd-network/sd-ipv4ll.c
src/libsystemd-network/sd-ndisc.c
src/libsystemd-network/sd-radv.c
src/libsystemd-network/test-acd.c
src/libsystemd-network/test-dhcp-client.c
src/libsystemd-network/test-dhcp6-client.c
src/libsystemd-network/test-ipv4ll-manual.c
src/libsystemd-network/test-ndisc-rs.c
src/libsystemd/meson.build
src/libsystemd/sd-bus/bus-container.c
src/libsystemd/sd-bus/bus-dump.c
src/libsystemd/sd-bus/bus-error.c
src/libsystemd/sd-bus/bus-gvariant.c
src/libsystemd/sd-bus/bus-match.c
src/libsystemd/sd-bus/bus-message.c
src/libsystemd/sd-bus/bus-slot.c
src/libsystemd/sd-bus/bus-socket.c
src/libsystemd/sd-bus/sd-bus.c
src/libsystemd/sd-bus/test-bus-benchmark.c
src/libsystemd/sd-bus/test-bus-signature.c
src/libsystemd/sd-device/sd-device.c
src/libsystemd/sd-event/sd-event.c
src/libsystemd/sd-event/test-event.c
src/libsystemd/sd-journal/journal-file.c
src/libsystemd/sd-journal/journal-vacuum.c
src/libsystemd/sd-journal/sd-journal.c
src/libsystemd/sd-journal/test-compress-benchmark.c
src/libsystemd/sd-journal/test-journal-verify.c
src/libsystemd/sd-login/sd-login.c
src/libsystemd/sd-netlink/netlink-message.c
src/libsystemd/sd-netlink/netlink-slot.c
src/libsystemd/sd-netlink/rtnl-message.c
src/libsystemd/sd-network/sd-network.c
src/libsystemd/sd-resolve/sd-resolve.c
src/libsystemd/sd-resolve/test-resolve.c
src/libudev/libudev.pc.in
src/libudev/meson.build
src/libudev/test-libudev.c
src/locale/keymap-util.c
src/locale/localectl.c
src/locale/meson.build
src/login/inhibit.c
src/login/loginctl.c
src/login/logind-button.c
src/login/logind-dbus.c
src/login/logind-inhibit.c
src/login/logind-session-device.c
src/login/logind-user.c
src/login/logind-utmp.c
src/login/pam_systemd.c
src/login/user-runtime-dir.c
src/machine-id-setup/machine-id-setup-main.c
src/machine/machinectl.c
src/machine/machined-varlink.c
src/modules-load/modules-load.c
src/mount/mount-tool.c
src/network/generator/main.c
src/network/meson.build
src/network/netdev/fou-tunnel.c
src/network/netdev/netdev.c
src/network/netdev/tunnel.c
src/network/networkctl.c
src/network/networkd-address.c
src/network/networkd-address.h
src/network/networkd-bridge-mdb.c
src/network/networkd-can.c
src/network/networkd-conf.c
src/network/networkd-dhcp-server.c
src/network/networkd-dhcp4.c
src/network/networkd-dhcp6.c
src/network/networkd-ipv4acd.c
src/network/networkd-link.c
src/network/networkd-lldp-tx.c
src/network/networkd-ndisc.c
src/network/networkd-neighbor.c
src/network/networkd-network-gperf.gperf
src/network/networkd-nexthop.c
src/network/networkd-queue.c
src/network/networkd-route.c
src/network/networkd-route.h
src/network/networkd-routing-policy-rule.c
src/network/networkd-setlink.c
src/network/networkd-sriov.c
src/network/networkd-util.c
src/network/networkd-util.h
src/network/tc/codel.c
src/network/tc/ets.c
src/network/tc/fifo.c
src/network/tc/fq-codel.c
src/network/tc/fq.c
src/network/tc/gred.c
src/network/tc/htb.c
src/network/tc/tbf.c
src/network/tc/tc.c
src/network/test-networkd-address.c [new file with mode: 0644]
src/network/wait-online/wait-online.c
src/notify/notify.c
src/nspawn/nspawn-bind-user.c
src/nspawn/nspawn-mount.c
src/nspawn/nspawn-stub-pid1.c
src/nspawn/nspawn.c
src/oom/oomctl.c
src/oom/oomd-manager.c
src/oom/oomd-util.c
src/oom/oomd.c
src/partition/growfs.c
src/partition/repart.c
src/path/path.c
src/portable/meson.build
src/portable/portable.c
src/portable/portablectl.c
src/resolve/resolvconf-compat.c
src/resolve/resolvectl.c
src/resolve/resolved-bus.c
src/resolve/resolved-conf.c
src/resolve/resolved-dns-dnssec.c
src/resolve/resolved-dns-packet.h
src/resolve/resolved-dns-scope.c
src/resolve/resolved-dns-search-domain.c
src/resolve/resolved-dns-server.c
src/resolve/resolved-dns-stub.c
src/resolve/resolved-dns-transaction.c
src/resolve/resolved-varlink.c
src/rpm/macros.systemd.in
src/rpm/meson.build
src/rpm/systemd-update-helper.in [new file with mode: 0755]
src/rpm/triggers.systemd.in
src/rpm/triggers.systemd.sh.in
src/run/run.c
src/shared/acl-util.c
src/shared/bpf-program.c
src/shared/btrfs-util.c
src/shared/btrfs-util.h
src/shared/bus-print-properties.c
src/shared/bus-unit-util.c
src/shared/bus-util.c
src/shared/clock-util.c
src/shared/clock-util.h
src/shared/condition.c
src/shared/copy.c
src/shared/copy.h
src/shared/creds-util.c
src/shared/devnode-acl.c
src/shared/discover-image.c
src/shared/dissect-image.c
src/shared/exec-util.c
src/shared/exec-util.h
src/shared/format-table.c
src/shared/gpt.c
src/shared/gpt.h
src/shared/import-util.c
src/shared/import-util.h
src/shared/install.c
src/shared/journal-importer.c
src/shared/json.c
src/shared/killall.c
src/shared/local-addresses.c
src/shared/logs-show.c
src/shared/mount-setup.c
src/shared/mount-util.c
src/shared/nscd-flush.c
src/shared/pretty-print.c
src/shared/rm-rf.c
src/shared/rm-rf.h
src/shared/seccomp-util.c
src/shared/selinux-util.c
src/shared/serialize.c
src/shared/service-util.c
src/shared/socket-netlink.c
src/shared/spawn-ask-password-agent.c
src/shared/spawn-polkit-agent.c
src/shared/tests.c
src/shared/tpm2-util.c
src/shared/tpm2-util.h
src/shared/udev-util.c
src/shared/user-record-show.c
src/shared/userdb.c
src/shared/utmp-wtmp.c
src/shared/varlink.c
src/shared/watchdog.c
src/shared/xml.c
src/shutdown/shutdown.c
src/sleep/sleep.c
src/socket-proxy/socket-proxyd.c
src/sysctl/sysctl.c
src/sysext/sysext.c
src/systemctl/systemctl-add-dependency.c
src/systemctl/systemctl-clean-or-freeze.c
src/systemctl/systemctl-compat-halt.c
src/systemctl/systemctl-compat-runlevel.c
src/systemctl/systemctl-compat-shutdown.c
src/systemctl/systemctl-compat-telinit.c
src/systemctl/systemctl-daemon-reload.c
src/systemctl/systemctl-enable.c
src/systemctl/systemctl-logind.c
src/systemctl/systemctl-set-property.c
src/systemctl/systemctl-show.c
src/systemctl/systemctl-start-special.c
src/systemctl/systemctl-util.c
src/systemctl/systemctl.c
src/systemd/meson.build
src/systemd/sd-bus-vtable.h
src/sysusers/sysusers.c
src/test/meson.build
src/test/test-bitmap.c
src/test/test-boot-timestamps.c
src/test/test-btrfs.c
src/test/test-calendarspec.c
src/test/test-chase-symlinks.c
src/test/test-date.c
src/test/test-escape.c
src/test/test-ether-addr-util.c [new file with mode: 0644]
src/test/test-format-util.c
src/test/test-hashmap-plain.c
src/test/test-import-util.c [new file with mode: 0644]
src/test/test-install-root.c
src/test/test-locale-util.c
src/test/test-path-util.c
src/test/test-proc-cmdline.c
src/test/test-procfs-util.c
src/test/test-strv.c
src/test/test-time-util.c
src/test/test-util.c
src/test/test-xattr-util.c
src/timedate/timedatectl.c
src/timesync/timesyncd-server.c
src/timesync/wait-sync.c
src/tmpfiles/test-offline-passwd.c
src/tmpfiles/tmpfiles.c
src/tty-ask-password-agent/tty-ask-password-agent.c
src/udev/cdrom_id/cdrom_id.c
src/udev/dmi_memory_id/dmi_memory_id.c
src/udev/meson.build
src/udev/net/link-config.c
src/udev/scsi_id/scsi_id.c
src/udev/test-udev-event.c
src/udev/udev-builtin-net_setup_link.c
src/udev/udev-event.c
src/udev/udev-rules.c
src/udev/udevadm-control.c
src/udev/udevadm-hwdb.c
src/udev/udevadm-info.c
src/udev/udevadm-monitor.c
src/udev/udevadm-settle.c
src/udev/udevadm-test-builtin.c
src/udev/udevadm-test.c
src/udev/udevadm-trigger.c
src/udev/udevadm.c
src/udev/udevd.c
src/udev/v4l_id/v4l_id.c
src/userdb/userdbctl.c
src/userdb/userwork.c
src/veritysetup/veritysetup.c
src/xdg-autostart-generator/xdg-autostart-service.c
sysctl.d/meson.build
test/TEST-13-NSPAWN-SMOKE/test.sh
test/TEST-52-HONORFIRSTSHUTDOWN/test.sh
test/meson.build
test/test-functions
test/test-network/conf/networkd-manage-foreign-routes-no.conf [new file with mode: 0644]
test/test-network/systemd-networkd-tests.py
test/units/testsuite-13.sh
test/units/testsuite-36.sh
test/units/testsuite-55.sh
test/units/testsuite-60.sh
tmpfiles.d/legacy.conf.in [moved from tmpfiles.d/legacy.conf with 90% similarity]
tmpfiles.d/meson.build
tools/git-contrib.sh
units/meson.build
units/systemd-boot-update.service [new file with mode: 0644]
units/systemd-homed.service.in

index 93f8b1c0f471a9e642595a3ee869a5be67c22343..83ec5ecf116efda85d854260f44deec96e1cddbc 100644 (file)
--- a/.lgtm.yml
+++ b/.lgtm.yml
@@ -10,6 +10,9 @@ extraction:
         - libp11-kit-dev
         - libssl-dev
         - python3-jinja2
+    after_prepare:
+      - pip3 install meson==0.53.2
+      - export PATH="/opt/work/.local/bin:$PATH"
   python:
     python_setup:
       version: 3
index 4545e30e0867d81889333b473bcfba427e557ca9..962c77913ebb5c2d045429a3f0739c3e196a757b 100644 (file)
@@ -39,4 +39,5 @@ jobs:
     targets:
     - fedora-rawhide-aarch64
     - fedora-rawhide-i386
+    - fedora-rawhide-ppc64le
     - fedora-rawhide-x86_64
diff --git a/README b/README
index 0e5c326debb9a5d8bfacbd7475555e2090c1e461..a8f23a0d5b95d1c39dd6695c58cef3367906a175 100644 (file)
--- a/README
+++ b/README
@@ -193,7 +193,7 @@ REQUIREMENTS:
         python-jinja2
         python-lxml (optional, required to build the indices)
         python >= 3.5
-        meson >= 0.46 (>= 0.49 is required to build position-independent executables)
+        meson >= 0.47 (>= 0.49 is required to build position-independent executables)
         ninja
         gcc, awk, sed, grep, and similar tools
         clang >= 10.0, llvm >= 10.0 (optional, required to build BPF programs
diff --git a/TODO b/TODO
index 7c5002e6b04d3f42400db1e214a6650202521d44..16a91fa02366eb5ff2f4d016a5c3d9dd624dfcb8 100644 (file)
--- a/TODO
+++ b/TODO
@@ -83,6 +83,8 @@ Janitorial Clean-ups:
 
 Features:
 
+* use credentials logic/TPM2 logic to store homed signing key
+
 * New udev block device symlink names:
   /dev/disk/by-parttypelabel/<pttype>/<ptlabel>. Use case: if pt label is used
   as partition image version string, this is a safe way to reference a specific
@@ -262,6 +264,8 @@ Features:
 
 * pid1: support new clone3() fork-into-cgroup feature
 
+* pid1: support new cgroup.kill to terminate all processes in a cgroup
+
 * pid1: also remove PID files of a service when the service starts, not just
   when it exits
 
@@ -376,9 +380,8 @@ Features:
   https://docs.microsoft.com/en-us/windows-hardware/design/device-experiences/modern-standby-wake-sources
   at the end).
 
-* We should probably replace /var/log/README, /etc/rc.d/README with symlinks
-  that are linked to these places instead of copied. After all they are
-  constant vendor data.
+* We should probably replace /etc/rc.d/README with a symlink to doc
+  content. After all it is constant vendor data.
 
 * maybe add kernel cmdline params: to force random seed crediting
 
@@ -425,6 +428,7 @@ Features:
 * paranoia: whenever we process passwords, call mlock() on the memory
   first. i.e. look for all places we use free_and_erasep() and
   augment them with mlock(). Also use MADV_DONTDUMP.
+  Alternatively (preferably?) use memfd_secret().
 
 * Move RestrictAddressFamily= to the new cgroup create socket
 
@@ -1015,10 +1019,6 @@ Features:
 
 * bootctl,sd-boot: actually honour the "architecture" key
 
-* sd-boot: add service that automatically runs "bootctl update" on every boot,
-  in a graceful way, so that updated /usr trees automatically propagate into
-  updated boot loaders on reboot.
-
 * bootctl:
   - teach it to prepare an ESP wholesale, i.e. with mkfs.vfat invocation
   - teach it to copy in unified kernel images and maybe type #1 boot loader spec entries from host
@@ -1187,6 +1187,9 @@ Features:
   - introduce API for "making room", that grows/shrinks home directory
     according to elastic parameters, discards blocks, and removes additional snapshots. Call it
     either from UI when disk space gets low
+  - when homed is in use, maybe start the user session manager in a mount namespace with MS_SLAVE,
+    so that mounts propagate down but not up - eg, user A setting up a backup volume
+    doesn't mean user B sees it
 
 * homed: during login resize fs automatically towards size goal. Specifically,
   resize to diskSize if possible, but leave a certain amount (configured by a
index be3b6e401de7bdc36c9afdb67c768db4746390af..e9155117b9a66fee60af4d0c78449fd2b62451f7 100644 (file)
@@ -76,10 +76,10 @@ variables. All EFI variables use the vendor UUID
   * `1 << 6` → The boot loader supports passing a random seed to the OS.
 
 * The EFI variable `LoaderRandomSeed` contains a binary random seed if set. It
-  is set by the boot loader to pass an entropy seed read from the ESP partition
-  to the OS. The system manager then credits this seed to the kernel's entropy
-  pool. It is the responsibility of the boot loader to ensure the quality and
-  integrity of the random seed.
+  is set by the boot loader to pass an entropy seed read from the ESP to the OS.
+  The system manager then credits this seed to the kernel's entropy pool. It is
+  the responsibility of the boot loader to ensure the quality and integrity of
+  the random seed.
 
 * The EFI variable `LoaderSystemToken` contains binary random data,
   persistently set by the OS installer. Boot loaders that support passing
index b87246ede12f1a4436741e38e87e9941e73f54a2..7b5b19700acb4b8bd867f1412e8bd0f111e2d649 100644 (file)
@@ -61,8 +61,8 @@ Everything described below is located on a placeholder file system `$BOOT`. The
 * On disks with GPT (GUID Partition Table)
   * If the OS is installed on a disk with GPT, and an Extended Boot Loader Partition or XBOOTLDR partition for short, i.e. a partition with GPT type GUID of `bc13c2ff-59e6-4262-a352-b275fd6f7172`, already exists, it should be used as `$BOOT`.
   * Otherwise, if the OS is installed on a disk with GPT, and an EFI System Partition or ESP for short, i.e. a partition with GPT type UID of `c12a7328-f81f-11d2-ba4b-00a0c93ec93b`) already exists and is large enough (let's say 250MB) and otherwise qualifies, it should be used as `$BOOT`.
-  * Otherwise, if the OS is installed on a disk with GPT, and if the ESP partition already exists but is too small, a new suitably sized (let's say 500MB) XBOOTLDR partition shall be created and used as `$BOOT`.
-  * Otherwise, if the OS is installed on a disk with GPT, and no ESP partition exists yet, a new suitably sized (let's say 500MB) ESP should be created and used as `$BOOT`.
+  * Otherwise, if the OS is installed on a disk with GPT, and if the ESP already exists but is too small, a new suitably sized (let's say 500MB) XBOOTLDR partition shall be created and used as `$BOOT`.
+  * Otherwise, if the OS is installed on a disk with GPT, and no ESP exists yet, a new suitably sized (let's say 500MB) ESP should be created and used as `$BOOT`.
 
 This placeholder file system shall be determined during _installation time_, and an fstab entry may be created. It should be mounted to either `/boot/` or `/efi/`. Additional locations like `/boot/efi/`, with `/boot/` being a separate file system, might be supported by implementations. This is not recommended because the mounting of `$BOOT` is then dependent on and requires the mounting of the intermediate file system.
 
index 368cac091fe443f86f6a594e804409731ed46b8d..4caa086dc5b32061db51edb1b73f8af3a54221c2 100644 (file)
@@ -46,6 +46,7 @@ Interface](https://systemd.io/BOOT_LOADER_INTERFACE).
 | `69dad710-2ce4-4e3c-b16c-21a1d49abed3` | _Root Partition (32-bit ARM)_ | ditto | ditto |
 | `b921b045-1df0-41c3-af44-4c6f280d3fae` | _Root Partition (64-bit ARM/AArch64)_ | ditto | ditto |
 | `993d8d3d-f80e-4225-855a-9daf8ed7ea97` | _Root Partition (Itanium/IA-64)_ | ditto | ditto |
+| `77055800-792c-4f94-b39a-98c91b762bb6` | _Root Partition (LoongArch 64-bit)_ | ditto | ditto |
 | `60d5a7fe-8e7d-435c-b714-3dd8162144e1` | _Root Partition (RISC-V 32-bit)_ | ditto | ditto |
 | `72ec70a6-cf74-40e6-bd49-4bda08e8f224` | _Root Partition (RISC-V 64-bit)_ | ditto | ditto |
 | `d13c5d3b-b5d1-422a-b29f-9454fdc89d76` | _Root Verity Partition (x86)_ | A dm-verity superblock followed by hash data | On systems with matching architecture, contains dm-verity integrity hash data for the matching root partition. If this feature is used the partition UUID of the root partition should be the first 128bit of the root hash of the dm-verity hash data, and the partition UUID of this dm-verity partition should be the final 128bit of it, so that the root partition and its verity partition can be discovered easily, simply by specifying the root hash. |
@@ -53,6 +54,7 @@ Interface](https://systemd.io/BOOT_LOADER_INTERFACE).
 | `7386cdf2-203c-47a9-a498-f2ecce45a2d6` | _Root Verity Partition (32-bit ARM)_ | ditto | ditto |
 | `df3300ce-d69f-4c92-978c-9bfb0f38d820` | _Root Verity Partition (64-bit ARM/AArch64)_ | ditto | ditto |
 | `86ed10d5-b607-45bb-8957-d350f23d0571` | _Root Verity Partition (Itanium/IA-64)_  | ditto | ditto |
+| `f3393b22-e9af-4613-a948-9d3bfbd0c535` | _Root Verity Partition (LoongArch 64-bit)_  | ditto | ditto |
 | `ae0253be-1167-4007-ac68-43926c14c5de` | _Root Verity Partition (RISC-V 32-bit)_  | ditto | ditto |
 | `b6ed5582-440b-4209-b8da-5ff7c419ea3d` | _Root Verity Partition (RISC-V 64-bit)_  | ditto | ditto |
 | `75250d76-8cc6-458e-bd66-bd47cc81a812` | _`/usr/` Partition (x86)_ | Any native, optionally in LUKS | Similar semantics to root partition, but just the `/usr/` partition. |
@@ -60,6 +62,7 @@ Interface](https://systemd.io/BOOT_LOADER_INTERFACE).
 | `7d0359a3-02b3-4f0a-865c-654403e70625` | _`/usr/` Partition (32-bit ARM)_ | ditto | ditto |
 | `b0e01050-ee5f-4390-949a-9101b17104e9` | _`/usr/` Partition (64-bit ARM/AArch64)_ | ditto | ditto |
 | `4301d2a6-4e3b-4b2a-bb94-9e0b2c4225ea` | _`/usr/` Partition (Itanium/IA-64)_ | ditto | ditto |
+| `e611c702-575c-4cbe-9a46-434fa0bf7e3f` | _`/usr/` Partition (LoongArch 64-bit)_ | ditto | ditto |
 | `b933fb22-5c3f-4f91-af90-e2bb0fa50702` | _`/usr/` Partition (RISC-V 32-bit)_ | ditto | ditto |
 | `beaec34b-8442-439b-a40b-984381ed097d` | _`/usr/` Partition (RISC-V 64-bit)_ | ditto | ditto |
 | `8f461b0d-14ee-4e81-9aa9-049b6fb97abd` | _`/usr/` Verity Partition (x86)_ | A dm-verity superblock followed by hash data | Similar semantics to root Verity partition, but just for the `/usr/` partition. |
@@ -67,6 +70,7 @@ Interface](https://systemd.io/BOOT_LOADER_INTERFACE).
 | `c215d751-7bcd-4649-be90-6627490a4c05` | _`/usr/` Verity Partition (32-bit ARM)_ | ditto | ditto |
 | `6e11a4e7-fbca-4ded-b9e9-e1a512bb664e` | _`/usr/` Verity Partition (64-bit ARM/AArch64)_ | ditto | ditto |
 | `6a491e03-3be7-4545-8e38-83320e0ea880` | _`/usr/` Verity Partition (Itanium/IA-64)_ | ditto | ditto |
+| `f46b2c26-59ae-48f0-9106-c50ed47f673d` | _`/usr/` Verity Partition (LoongArch 64-bit)_ | ditto | ditto |
 | `cb1ee4e3-8cd0-4136-a0a4-aa61a32e8730` | _`/usr/` Verity Partition (RISC-V 32-bit)_ | ditto | ditto |
 | `8f1056be-9b05-47c4-81d6-be53128e5b54` | _`/usr/` Verity Partition (RISC-V 64-bit)_ | ditto | ditto |
 | `933ac7e1-2eb4-4f13-b844-0e14e2aef915` | _Home Partition_ | Any native, optionally in LUKS | The first partition with this type UUID on the disk containing the root partition is automatically mounted to `/home/`.  If the partition is encrypted with LUKS, the device mapper file will be named `/dev/mapper/home`. |
@@ -221,13 +225,13 @@ We are not. `/etc/fstab` always overrides automatic discovery and is indeed
 mentioned in the specifications.  We are simply trying to make the boot and
 installation processes of Linux a bit more robust and self-descriptive.
 
-### Why did you only define the root partition for x86, x86-64, ARM, ARM64, ia64, riscv32, riscv64?
+### Why did you only define the root partition for these listed architectures?
 
 The automatic discovery of the root partition is defined to operate on the disk
 containing the current EFI System Partition (ESP). Since EFI only exists on
-x86, x86-64, ia64, ARM and RISC-V so far, we only defined root partition UUIDs for
-these architectures.  Should EFI become more common on other architectures, we
-can define additional UUIDs for them.
+x86, x86-64, ia64, ARM, LoongArch and RISC-V so far, we only defined root
+partition UUIDs for these architectures.  Should EFI become more common on
+other architectures, we can define additional UUIDs for them.
 
 ### Why define distinct root partition UUIDs for the various architectures?
 
similarity index 100%
rename from docs/var-log/README
rename to docs/var-log/README.logs
index ba7957711dd6d955332a9f775756d7283a76affb..35f756cafec846cb4c239be41c1d9ce566a053e1 100644 (file)
@@ -1,6 +1,6 @@
 # SPDX-License-Identifier: LGPL-2.1-or-later
 
 if conf.get('HAVE_SYSV_COMPAT') == 1 and get_option('create-log-dirs')
-        install_data('README',
-                     install_dir : '/var/log')
+        install_data('README.logs',
+                     install_dir : docdir)
 endif
index 9a787b52f21cb9fc7a415eb1c6f21378150cbe42..2e0614369709db552a08a181c507b249d3dfd0bf 100644 (file)
@@ -1303,7 +1303,6 @@ evdev:atkbd:dmi:bvn*:bvr*:bd*:svnMICRO-STAR*:pnU90/U100:*
 # Keymaps MSI Prestige And MSI Modern FnKeys and Special keys
 evdev:atkbd:dmi:bvn*:bvr*:bd*:svnMicro-Star*:pn*Prestige*:*
 evdev:atkbd:dmi:bvn*:bvr*:bd*:svnMicro-Star*:pn*Modern*:*
- KEYBOARD_KEY_56=backslash                              # Secondary backslash key
  KEYBOARD_KEY_f1=f20                                    # Fn+F5 Micmute
  KEYBOARD_KEY_76=f21                                    # Fn+F4 Toggle touchpad, sends meta+ctrl+toggle
  KEYBOARD_KEY_91=prog1                                  # Fn+F7 Creation Center, sometime F7
index f1744b8d78cc7f741bd0b00ca2e205071c3a4340..9859ce5b124097f811dc2fdb48f47dc467922c59 100644 (file)
@@ -289,10 +289,10 @@ sensor:modalias:acpi:*KIOX000A*:dmi:*svn*CytrixTechnology:*pn*Complex11t:*
 sensor:modalias:platform:HID-SENSOR-200073:dmi:*svnDell*:pnVostro5581:*
  ACCEL_LOCATION=base
 
-sensor:modalias:platform:HID-SENSOR-200073:dmi:*svnDell*:pnLatitude9520:*:ct10:*
+sensor:modalias:platform:HID-SENSOR-200073:dmi:*svnDell*:sku0A3E:*
  ACCEL_LOCATION=base
 
-sensor:modalias:platform:HID-SENSOR-200073:dmi:*svnDell*:pnLatitude7420:*
+sensor:modalias:platform:HID-SENSOR-200073:dmi:*svnDell*:sku0B0B:*
  ACCEL_LOCATION=base
 
 # Dell Venue 8 Pro 3845
@@ -847,6 +847,7 @@ sensor:modalias:acpi:KIOX000A*:dmi:*:svnTrekStor:pnSurfTabtwin10.1:*
 sensor:modalias:acpi:KIOX000A*:dmi:*:svnTREKSTOR*:pnPrimetabS11B:*
 sensor:modalias:acpi:KIOX000A*:dmi:*:svnTREKSTOR:pnPrimetabT13B:*
 sensor:modalias:acpi:BOSC0200*:dmi:*:svnTrekStor*:pnSurfTabtwin11.6:*
+sensor:modalias:acpi:BOSC0200*:dmi:*:svnTrekStor*:pnSurfTabduoW110.1(VT4):*
  ACCEL_MOUNT_MATRIX=1, 0, 0; 0, -1, 0; 0, 0, 1
 
 # alternative version of Trekstor's SurfTab Twin 11.6
index 0a96b5553a540c4b10df8b9f088759fd01164428..4f3560e37f869ad8c405d7054d4ec30b6cb5e7d8 100644 (file)
@@ -49,7 +49,7 @@ if conf.get('ENABLE_HWDB') == 1
 
         if install_sysconfdir
                 meson.add_install_script('sh', '-c',
-                                         mkdir_p.format(join_paths(sysconfdir, 'udev/hwdb.d')))
+                                         mkdir_p.format(sysconfdir / 'udev/hwdb.d'))
 
                 meson.add_install_script('sh', '-c',
                                          'test -n "$DESTDIR" || @0@/systemd-hwdb update'.format(rootbindir))
index 81033158f64b3917f122d7843c911a660469285e..a958cde7df84d0d8f1285ced7e87fed182bb661d 100644 (file)
 
       <varlistentry>
         <term><option>--graceful</option></term>
-        <listitem><para>Ignore failure when the EFI System Partition cannot be found, or when EFI variables
-        cannot be written. Currently only applies to random seed operations.</para></listitem>
+        <listitem><para>Ignore failure when the EFI System Partition cannot be found, when EFI variables
+        cannot be written, or a different or newer boot loader is already installed. Currently only applies
+        to random seed and update operations.</para></listitem>
       </varlistentry>
 
       <varlistentry>
         <term><option>--make-machine-id-directory=yes|no|auto</option></term>
         <listitem><para>Control creation and deletion of the top-level machine ID directory on the file
-        system containing boot loader entries (i.e. beneath the file system returned by
-        <option>--print-boot-path</option> above) during <option>install</option> and
+        system containing boot loader entries (i.e. beneath the file system returned by the
+        <option>--print-boot-path</option> option, see above) during <option>install</option> and
         <option>remove</option>, respectively.  <literal>auto</literal> is equivalent to
         <literal>yes</literal> if <filename>/etc/machine-id</filename> resides on a filesystem other than
         tmpfs and <literal>no</literal> otherwise (in the latter case the machine ID is likely transient and
index 28e6017c7db28664569c26b22e17dfa02a4b8e97..1751191ec0cb12cc8b899c78295f98f8ccf64ed4 100644 (file)
       <varlistentry>
         <term><varname>ProcessSizeMax=</varname></term>
 
-        <listitem><para>The maximum size in bytes of a core
-        which will be processed. Core dumps exceeding this size
-        may be stored, but the backtrace will not be generated.
-        Like other sizes in this same config file, the usual
-        suffixes to the base of 1024 are allowed (B, K, M,
-        G, T, P, and E.)</para>
+        <listitem><para>The maximum size in bytes of a core which will be processed. Core dumps exceeding
+        this size may be stored, but the backtrace will not be generated.  Like other sizes in this same
+        config file, the usual suffixes to the base of 1024 are allowed (B, K, M, G, T, P, and E).</para>
 
         <para>Setting <varname>Storage=none</varname> and <varname>ProcessSizeMax=0</varname>
         disables all coredump handling except for a log entry.</para>
@@ -99,9 +96,8 @@
         <term><varname>ExternalSizeMax=</varname></term>
         <term><varname>JournalSizeMax=</varname></term>
 
-        <listitem><para>The maximum (compressed or uncompressed) size in bytes of a
-        core to be saved. Unit suffixes are allowed just as in
-        <option>ProcessSizeMax=</option></para></listitem>.
+        <listitem><para>The maximum (compressed or uncompressed) size in bytes of a core to be saved. Unit
+        suffixes are allowed just as in <option>ProcessSizeMax=</option>.</para></listitem>
       </varlistentry>
 
       <varlistentry>
         by core dumps might temporarily exceed these limits while
         core dumps are processed. Note that old core dumps are also
         removed based on time via
-        <citerefentry><refentrytitle>systemd-tmpfiles</refentrytitle><manvolnum>8</manvolnum></citerefentry>. Set
-        either value to 0 to turn off size-based
-        clean-up.</para></listitem>
+        <citerefentry><refentrytitle>systemd-tmpfiles</refentrytitle><manvolnum>8</manvolnum></citerefentry>.
+        Set either value to 0 to turn off size-based cleanup.</para></listitem>
       </varlistentry>
     </variablelist>
 
index 6ceed41b0598e0f720bb993235ccb3e44ff4ec71..d45ed753b25502c368efbfef7953215bd08c2493 100644 (file)
         <term><option>-1</option></term>
 
         <listitem><para>Show information of the most recent core dump only, instead of listing all known core
-        dumps. (Equivalent to <option>--reverse -n 1</option></para></listitem>
+        dumps. Equivalent to <option>--reverse -n 1</option>.</para></listitem>
       </varlistentry>
 
       <varlistentry>
index b0e95ce841c90cb964726bceade0e5b98bdb08ea..39b9515c45234aae202def276b03ce5ac8747f51 100644 (file)
@@ -66,7 +66,7 @@
     <ulink url="https://tools.ietf.org/html/rfc1035#section-5">RFC 1035, Section 5</ulink>. One <constant
     class='dns'>DS</constant> or <constant class='dns'>DNSKEY</constant> resource record may be listed per
     line. Empty lines and lines starting with <literal>#</literal> or <literal>;</literal> are ignored, which
-    may be used for commenting. A <consant class='dns'>DS</consant> resource record is specified like in the
+    may be used for commenting. A <constant class='dns'>DS</constant> resource record is specified like in the
     following example:</para>
 
     <programlisting>. IN DS 19036 8 2 49aac11d7b6f6446702e54a1607371607a1a41855200fd2ce1cdde32f24e8fb5</programlisting>
index 900bb2a3afce62f84b33eeec72f3f476e32f1e2a..4132f826a8962de7784f35dbcf02f45578ce2a0a 100644 (file)
@@ -37,7 +37,7 @@ man_pages = []
 html_pages = []
 source_xml_files = []
 dbus_docs = []
-foreach tuple : xsltproc.found() ? manpages : []
+foreach tuple : manpages
         stem = tuple[0]
         section = tuple[1]
         aliases = tuple[2]
@@ -54,49 +54,50 @@ foreach tuple : xsltproc.found() ? manpages : []
                 htmlaliases += alias + '.html'
         endforeach
 
-        mandirn = join_paths(get_option('mandir'), 'man' + section)
+        mandirn = get_option('mandir') / ('man' + section)
 
         if condition == '' or conf.get(condition) == 1
-                p1 = custom_target(
-                        man,
-                        input : xml,
-                        output : [man] + manaliases,
-                        command : xslt_cmd + [custom_man_xsl, '@INPUT@'],
-                        depends : custom_entities_ent,
-                        install : want_man,
-                        install_dir : mandirn)
-                man_pages += p1
-
-                p2 = []
-                foreach htmlalias : htmlaliases
-                        link = custom_target(
-                                htmlalias,
-                                output : htmlalias,
-                                command : [ln, '-fs', html, '@OUTPUT@'])
-                        if want_html
-                                dst = join_paths(docdir, 'html', htmlalias)
-                                cmd = 'ln -fs @0@ $DESTDIR@1@'.format(html, dst)
-                                meson.add_install_script('sh', '-c', cmd)
-                                p2 += link
-                        endif
-                        html_pages += link
-                endforeach
-
-                p3 = custom_target(
-                        html,
-                        input : xml,
-                        output : html,
-                        command : xslt_cmd + [custom_html_xsl, '@INPUT@'],
-                        depends : [custom_entities_ent, p2],
-                        install : want_html,
-                        install_dir : join_paths(docdir, 'html'))
-                html_pages += p3
-
                 file = files(tuple[0] + '.xml')
-                source_xml_files += file
                 if tuple[0].startswith('org.freedesktop.')
                         dbus_docs += file
                 endif
+
+                if xsltproc.found()
+                        p1 = custom_target(
+                                man,
+                                input : xml,
+                                output : [man] + manaliases,
+                                command : xslt_cmd + [custom_man_xsl, '@INPUT@'],
+                                depends : custom_entities_ent,
+                                install : want_man,
+                                install_dir : mandirn)
+                        man_pages += p1
+
+                        p2 = []
+                        foreach htmlalias : htmlaliases
+                                link = custom_target(
+                                        htmlalias,
+                                        output : htmlalias,
+                                        command : [ln, '-fs', html, '@OUTPUT@'])
+                                if want_html
+                                        dst = docdir / 'html' / htmlalias
+                                        cmd = 'ln -fs @0@ $DESTDIR@1@'.format(html, dst)
+                                        meson.add_install_script('sh', '-c', cmd)
+                                        p2 += link
+                                endif
+                                html_pages += link
+                        endforeach
+
+                        p3 = custom_target(
+                                html,
+                                input : xml,
+                                output : html,
+                                command : xslt_cmd + [custom_html_xsl, '@INPUT@'],
+                                depends : [custom_entities_ent, p2],
+                                install : want_html,
+                                install_dir : docdir / 'html')
+                        html_pages += p3
+                endif
         else
                 message('Skipping @0@.@1@ because @2@ is false'.format(stem, section, condition))
         endif
@@ -132,7 +133,7 @@ foreach tuple : xsltproc.found() ? [['systemd.directives', '7', systemd_directiv
         html = stem + '.html'
         man = stem + '.' + section
 
-        mandirn = join_paths(get_option('mandir'), 'man' + section)
+        mandirn = get_option('mandir') / ('man' + section)
 
         p1 = custom_target(
                 man,
@@ -152,7 +153,7 @@ foreach tuple : xsltproc.found() ? [['systemd.directives', '7', systemd_directiv
                         output : htmlalias,
                         command : [ln, '-fs', html, '@OUTPUT@'])
                 if want_html
-                        dst = join_paths(docdir, 'html', htmlalias)
+                        dst = docdir / 'html' / htmlalias
                         cmd = 'ln -fs @0@ $DESTDIR@1@'.format(html, dst)
                         meson.add_install_script('sh', '-c', cmd)
                         p2 += link
@@ -167,7 +168,7 @@ foreach tuple : xsltproc.found() ? [['systemd.directives', '7', systemd_directiv
                 command : xslt_cmd + [custom_html_xsl, '@INPUT@'],
                 depends : [custom_entities_ent, p2],
                 install : want_html and have_lxml,
-                install_dir : join_paths(docdir, 'html'))
+                install_dir : docdir / 'html')
         html_pages += p3
 endforeach
 
@@ -213,3 +214,26 @@ configure_file(
         input : 'html.in',
         output : 'html',
         configuration : buildroot_substs)
+
+############################################################
+
+update_dbus_docs = custom_target(
+        'update-dbus-docs',
+        output : 'update-dbus-docs',
+        command : [update_dbus_docs_py, '--build-dir', project_build_root, '@INPUT@'],
+        input : dbus_docs)
+
+if conf.get('BUILD_MODE_DEVELOPER') == 1
+        test('dbus-docs-fresh',
+             update_dbus_docs_py,
+             args : ['--build-dir', project_build_root, '--test', dbus_docs])
+endif
+
+update_man_rules = custom_target(
+        'update-man-rules',
+        output : 'update-man-rules',
+        command : [sh, '-c',
+                   'cd @0@ && '.format(project_build_root) +
+                   'python3 @0@/tools/update-man-rules.py $(find @0@ -wholename "*/man/*.xml") >t && '.format(project_source_root) +
+                   'mv t @0@/rules/meson.build'.format(meson.current_source_dir())],
+        depends : custom_entities_ent)
index 98eb0ec77edaedbbcf7361753bd74c0d3f1cdbe7..f9d0ff43f4399463e07f31b2211c67711c4dd08b 100644 (file)
     <para>To activate the NSS modules, add <literal>myhostname</literal> to the line starting with
     <literal>hosts:</literal> in <filename>/etc/nsswitch.conf</filename>.</para>
 
-    <para>It is recommended to place <literal>myhostname</literal> either between <literal>resolve</literal>
-    and "traditional" modules like <literal>dns</literal>, or after them. In the first version, well-known
-    names like <literal>localhost</literal> and the machine hostname are given higher priority than the
-    external configuration. This is recommended when the external DNS servers and network are not absolutely
-    trusted. In the second version, external configuration is given higher priority and
-    <command>nss-myhostname</command> only provides a fallback mechanism. This might be suitable in closely
-    controlled networks, for example on a company LAN.</para>
+    <para>It is recommended to place <literal>myhostname</literal> after <literal>file</literal> and before <literal>dns</literal>.
+    This resolves well-known hostnames like <literal>localhost</literal>
+    and the machine hostnames locally. It is consistent with the behaviour
+    of <command>nss-resolve</command>, and still allows overriding via
+    <filename>/etc/hosts</filename>.</para>
+
+    <para>Please keep in mind that <command>nss-myhostname</command> (and <command>nss-resolve</command>) also resolve
+    in the other direction — from locally attached IP adresses to
+    hostnames. If you rely on that lookup being provided by DNS, you might
+    want to order things differently.
+    </para>
   </refsect1>
 
   <refsect1>
@@ -95,10 +99,7 @@ shadow:         compat systemd
 gshadow:        files systemd
 
 
-# Either (untrusted network, see above):
 hosts:          mymachines resolve [!UNAVAIL=return] files <command>myhostname</command> dns
-# Or (only trusted networks):
-hosts:          mymachines resolve [!UNAVAIL=return] files dns <command>myhostname</command>
 networks:       files
 
 protocols:      db files
index 97c3768100bacac9ef1fc51e3ff67f59e2e7a785..4f9e1f9c5a58f27e2702216df5bb0f93ec3ec17f 100644 (file)
     it is still recommended (see examples below) to keep <command>nss-myhostname</command> configured in
     <filename>/etc/nsswitch.conf</filename>, to keep those names resolveable if
     <command>systemd-resolved</command> is not running.</para>
+
+    <para>Please keep in mind that <command>nss-myhostname</command> (and <command>nss-resolve</command>) also resolve
+    in the other direction — from locally attached IP adresses to
+    hostnames. If you rely on that lookup being provided by DNS, you might
+    want to order things differently.
+    </para>
   </refsect1>
 
   <refsect1>
index 734a9a4a0726a8ca166ad8732c24e820acd6f808..b7b453825e303f660be2b8b1887ce1884d56df1d 100644 (file)
@@ -67,7 +67,7 @@
 
     <para>This is a simple mechanism to provide static user and group records via JSON drop-in files. Such
     user records should be defined in the format described by the <ulink
-    url="https://systemd.io/USER_RECORD">JSON User Record</ulink> specification and be placed in one of the
+    url="https://systemd.io/USER_RECORD">JSON User Records</ulink> specification and be placed in one of the
     aforementioned directories under a file name composed of the user name suffixed with
     <filename>.user</filename>, with a world-readable access mode. A symlink named after the user record's
     UID formatted in decimal and suffixed with <filename>.user</filename> pointing to the primary record file
index fb24eda18252c94102eeca6bdde5f3c433149ff5..a7c60183aefe1b8b136bf922d9549a629c64413a 100644 (file)
 
           <listitem><para>A lower-case string (mostly numeric, no spaces or other characters outside of 0–9,
           a–z, ".", "_" and "-") identifying the operating system extensions support level, to indicate which
-          extension images are supported. See:
+          extension images are supported. See
           <citerefentry><refentrytitle>systemd-sysext</refentrytitle><manvolnum>8</manvolnum></citerefentry>)
           for more information.</para>
 
index 24174213e2831a4c74f9339087db7679b87b1a31..5e3761ac50e4dddfdca43327633d7802a495d15a 100644 (file)
@@ -33,7 +33,7 @@
     and hence the systemd control group hierarchy.</para>
 
     <para>The module also applies various resource management and runtime parameters to the new session, as
-    configured in the <ulink url="https://systemd.io/USER_RECORD">JSON User Record</ulink> of the user, when
+    configured in the <ulink url="https://systemd.io/USER_RECORD">JSON User Records</ulink> of the user, when
     one is defined.</para>
 
     <para>On login, this module — in conjunction with <filename>systemd-logind.service</filename> — ensures the
index da1dea986f0aa35828ab8939a5402955a4e5d562..d3059e9ec60d3cef9b4d01e6a7039fd97349f4a2 100644 (file)
                 <entry>Verity data for the ia64 root file system partition</entry>
               </row>
 
+              <row>
+                <entry><constant>root-loongarch64</constant></entry>
+                <entry>Root file system partition for the LoongArch 64-bit architecture</entry>
+              </row>
+
+              <row>
+                <entry><constant>root-loongarch64-verity</constant></entry>
+                <entry>Verity data for the LoongArch 64-bit root file system partition</entry>
+              </row>
+
               <row>
                 <entry><constant>root-riscv32</constant></entry>
                 <entry>Root file system partition for the RISC-V 32-bit architecture</entry>
                 <entry>Verity data for the ia64 <filename>/usr/</filename> file system partition</entry>
               </row>
 
+              <row>
+                <entry><constant>usr-loongarch64</constant></entry>
+                <entry><filename>/usr/</filename> file system partition for the LoongArch 64-bit architecture</entry>
+              </row>
+
+              <row>
+                <entry><constant>usr-loongarch64-verity</constant></entry>
+                <entry>Verity data for the LoongArch 64-bit <filename>/usr/</filename> file system partition</entry>
+              </row>
+
               <row>
                 <entry><constant>usr-riscv32</constant></entry>
                 <entry><filename>/usr/</filename> file system partition for the RISC-V 32-bit architecture</entry>
         <para>If the special value <literal>auto</literal> is specified, the source to copy from is
         automatically picked up from the running system (or the image specified with
         <option>--image=</option> — if used). A partition that matches both the configured partition type (as
-        declared with <varname>Type=</varname> above), and the currently mounted directory appropriate for
-        that partition type is determined. For example, if the partition type is set to
+        declared with <varname>Type=</varname> described above), and the currently mounted directory
+        appropriate for that partition type is determined. For example, if the partition type is set to
         <literal>root</literal> the partition backing the root directory (<filename>/</filename>) is used as
         source to copy from — if its partition type is set to <literal>root</literal> as well. If the
         declared type is <literal>usr</literal> the partition backing <filename>/usr/</filename> is used as
       <varlistentry>
         <term><varname>MakeDirectories=</varname></term>
 
-        <listitem><para>akes one or more absolute paths, separated by whitespace, each declaring a directory
+        <listitem><para>Takes one or more absolute paths, separated by whitespace, each declaring a directory
         to create within the new file system. Behaviour is similar to <varname>CopyFiles=</varname>, but
         instead of copying in a set of files this just creates the specified directories with the default
         mode of 0755 owned by the root user and group, plus all their parent directories (with the same
         are copied in or the file system configured with <varname>Format=</varname> is created.</para>
 
         <para>The LUKS2 UUID is automatically derived from the partition UUID in a stable fashion. If
-        <literal>key-file</literal> or <literal>key-file+tpm2</literal> is used a key is added to the LUKS2
-        superblock, configurable with the <option>--key-file=</option> switch to
+        <literal>key-file</literal> or <literal>key-file+tpm2</literal> is used, a key is added to the LUKS2
+        superblock, configurable with the <option>--key-file=</option> option to
         <command>systemd-repart</command>. If <literal>tpm2</literal> or <literal>key-file+tpm2</literal> is
-        used a key is added to the LUKS2 superblock that is enrolled to the local TPM2 chip, as configured
+        used, a key is added to the LUKS2 superblock that is enrolled to the local TPM2 chip, as configured
         with the <option>--tpm2-device=</option> and <option>--tpm2-pcrs=</option> options to
         <command>systemd-repart</command>.</para>
 
         has no effect on explicit mounts, such as those done via <citerefentry
         project='man-pages'><refentrytitle>mount</refentrytitle><manvolnum>8</manvolnum></citerefentry> or
         <citerefentry
-        project='man-pages'><refentrytitle>fstab</refentrytitle><manvolnum>5</manvolnum></citerefentry></para>
+        project='man-pages'><refentrytitle>fstab</refentrytitle><manvolnum>5</manvolnum></citerefentry>.</para>
 
         <para>If both bit 50 and 59 are set for a partition (i.e. the partition is marked both read-only and
         marked for file system growing) the latter is typically without effect: the read-only flag takes
index 66477b3500a58933d2e8469d08eeb013ba2e3a32..d6a410e797ca135576e9584280f9f6e4e4e326d7 100644 (file)
@@ -39,7 +39,6 @@
         <paramdef>const char *<parameter>interface</parameter></paramdef>
         <paramdef>const char *<parameter>member</parameter></paramdef>
         <paramdef>sd_bus_error *<parameter>ret_error</parameter></paramdef>
-        <paramdef>sd_bus_message **<parameter>reply</parameter></paramdef>
         <paramdef>const char *<parameter>type</parameter></paramdef>
         <paramdef>...</paramdef>
       </funcprototype>
@@ -52,7 +51,6 @@
         <paramdef>const char *<parameter>interface</parameter></paramdef>
         <paramdef>const char *<parameter>member</parameter></paramdef>
         <paramdef>sd_bus_error *<parameter>ret_error</parameter></paramdef>
-        <paramdef>sd_bus_message **<parameter>reply</parameter></paramdef>
         <paramdef>const char *<parameter>type</parameter></paramdef>
         <paramdef>va_list <parameter>ap</parameter></paramdef>
       </funcprototype>
     <citerefentry><refentrytitle>sd_bus_call_method</refentrytitle><manvolnum>3</manvolnum></citerefentry>.
     </para>
 
-    <para><function>sd_bus_set_property()</function> sets a D-Bus property. On success, the response
-    is stored in <parameter>reply</parameter>. If setting the property fails or an internal error
-    occurs, an error is returned and an extended description of the error is optionally stored in
-    <parameter>ret_error</parameter> if it is not <constant>NULL</constant>.
+    <para><function>sd_bus_set_property()</function> sets a D-Bus property. If setting the property
+    fails or an internal error occurs, an error is returned and an extended description of the error
+    is optionally stored in <parameter>ret_error</parameter> if it is not <constant>NULL</constant>.
     <parameter>type</parameter> and the arguments that follow it describe the new value of the
     property and must follow the format described in
     <citerefentry><refentrytitle>sd_bus_message_append</refentrytitle><manvolnum>3</manvolnum></citerefentry>.
index 8402b9508a0e2eeb658ec2f67bca60bc03923ab5..5a133dea75b158cf621f45126c713a4042e32000 100644 (file)
@@ -552,38 +552,62 @@ Jan 12 10:46:45 example.com bluetoothd[8900]: gatt-time-server: Input/output err
         </varlistentry>
 
         <varlistentry>
-          <term><command>bind</command> <replaceable>UNIT</replaceable> <replaceable>PATH</replaceable> [<replaceable>PATH</replaceable>]</term>
-
-          <listitem><para>Bind mounts a file or directory from the host into the specified unit's view. The first path
-          argument is the source file or directory on the host, the second path argument is the destination file or
-          directory in the unit's view. When the latter is omitted, the destination path in the unit's view is the same as
-          the source path on the host. When combined with the <option>--read-only</option> switch, a ready-only bind
-          mount is created. When combined with the <option>--mkdir</option> switch, the destination path is first created
-          before the mount is applied. Note that this option is currently only supported for units that run within a mount
-          namespace (e.g.: with <option>RootImage=</option>, <option>PrivateMounts=</option>, etc.). This command supports bind
-          mounting directories, regular files, device nodes, <constant>AF_UNIX</constant> socket nodes, as well as FIFOs.
-          The bind mount is ephemeral, and it is undone as soon as the current unit process exists.
-          Note that the namespace mentioned here, where the bind mount will be added to, is the one where the main service
-          process runs, as other processes run in distinct namespaces (e.g.: <option>ExecReload=</option>,
-          <option>ExecStartPre=</option>, etc.) </para></listitem>
-        </varlistentry>
-
-        <varlistentry>
-          <term><command>mount-image</command> <replaceable>UNIT</replaceable> <replaceable>IMAGE</replaceable> [<replaceable>PATH</replaceable> [<replaceable>PARTITION_NAME</replaceable>:<replaceable>MOUNT_OPTIONS</replaceable>]]</term>
-
-          <listitem><para>Mounts an image from the host into the specified unit's view. The first path argument is the source
-          image on the host, the second path argument is the destination directory in the unit's view (ie: inside
-          <option>RootImage=</option>/<option>RootDirectory=</option>). Any following argument is interpreted as a
-          colon-separated tuple of partition name and comma-separated list of mount options for that partition. The format is the
-          same as the service <option>MountImages=</option> setting. When combined with the <option>--read-only</option> switch, a
-          ready-only mount is created. When combined with the <option>--mkdir</option> switch, the destination path is first
-          created before the mount is applied. Note that this option is currently only supported for units that run within a mount
-          namespace (e.g.: with <option>RootImage=</option>, <option>PrivateMounts=</option>, etc.).
-          Note that the namespace mentioned here, where the image mount will be added to, is the one where the main service
-          process runs, as other processes run in distinct namespaces (e.g.: <option>ExecReload=</option>,
-          <option>ExecStartPre=</option>, etc.). Example:
+          <term>
+            <command>bind</command>
+            <replaceable>UNIT</replaceable>
+            <replaceable>PATH</replaceable>
+            [<replaceable>PATH</replaceable>]
+          </term>
+
+          <listitem><para>Bind-mounts a file or directory from the host into the specified unit's mount
+          namespace. The first path argument is the source file or directory on the host, the second path
+          argument is the destination file or directory in the unit's mount namespace. When the latter is
+          omitted, the destination path in the unit's mount namespace is the same as the source path on the
+          host. When combined with the <option>--read-only</option> switch, a ready-only bind mount is
+          created. When combined with the <option>--mkdir</option> switch, the destination path is first
+          created before the mount is applied.</para>
+
+          <para>Note that this option is currently only supported for units that run within a mount namespace
+          (e.g.: with <option>RootImage=</option>, <option>PrivateMounts=</option>, etc.). This command
+          supports bind-mounting directories, regular files, device nodes, <constant>AF_UNIX</constant>
+          socket nodes, as well as FIFOs.  The bind mount is ephemeral, and it is undone as soon as the
+          current unit process exists. Note that the namespace mentioned here, where the bind mount will be
+          added to, is the one where the main service process runs. Other processes (those exececuted by
+          <option>ExecReload=</option>, <option>ExecStartPre=</option>, etc.) run in distinct namespaces.
+          </para></listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term>
+            <command>mount-image</command>
+            <replaceable>UNIT</replaceable>
+            <replaceable>IMAGE</replaceable>
+            [<replaceable>PATH</replaceable>
+            [<replaceable>PARTITION_NAME</replaceable>:<replaceable>MOUNT_OPTIONS</replaceable>]]
+          </term>
+
+          <listitem><para>Mounts an image from the host into the specified unit's mount namespace. The first
+          path argument is the source image on the host, the second path argument is the destination
+          directory in the unit's mount namespace (i.e. inside
+          <option>RootImage=</option>/<option>RootDirectory=</option>). The following argument, if any, is
+          interpreted as a colon-separated tuple of partition name and comma-separated list of mount options
+          for that partition. The format is the same as the service <option>MountImages=</option>
+          setting. When combined with the <option>--read-only</option> switch, a ready-only mount is
+          created. When combined with the <option>--mkdir</option> switch, the destination path is first
+          created before the mount is applied.</para>
+
+          <para>Note that this option is currently only supported for units that run within a mount namespace
+          (i.e. with <option>RootImage=</option>, <option>PrivateMounts=</option>, etc.). Note that the
+          namespace mentioned here where the image mount will be added to, is the one where the main service
+          process runs. Note that the namespace mentioned here, where the bind mount will be
+          added to, is the one where the main service process runs. Other processes (those exececuted by
+          <option>ExecReload=</option>, <option>ExecStartPre=</option>, etc.) run in distinct namespaces.
+          </para>
+
+          <para>Example:
           <programlisting>systemctl mount-image foo.service /tmp/img.raw /var/lib/image root:ro,nosuid</programlisting>
-          <programlisting>systemctl mount-image --mkdir bar.service /tmp/img.raw /var/lib/baz/img</programlisting></para></listitem>
+          <programlisting>systemctl mount-image --mkdir bar.service /tmp/img.raw /var/lib/baz/img</programlisting>
+          </para></listitem>
         </varlistentry>
 
         <varlistentry>
@@ -2185,9 +2209,9 @@ Jan 12 10:46:45 example.com bluetoothd[8900]: gatt-time-server: Input/output err
         <term><option>--lines=</option></term>
 
         <listitem>
-          <para>When used with <command>status</command>, controls the number of journal lines to show, counting from
-          the most recent ones. Takes a positive integer argument, or 0 to disable journal output. Defaults to
-          10.</para>
+          <para>When used with <command>status</command>, controls the number of journal lines to show,
+          counting from the most recent ones. Takes a positive integer argument, or 0 to disable journal
+          output. Defaults to 10.</para>
         </listitem>
       </varlistentry>
 
@@ -2208,8 +2232,9 @@ Jan 12 10:46:45 example.com bluetoothd[8900]: gatt-time-server: Input/output err
         <term><option>--firmware-setup</option></term>
 
         <listitem>
-          <para>When used with the <command>reboot</command> command, indicate to the system's firmware to reboot into
-          the firmware setup interface. Note that this functionality is not available on all systems.</para>
+          <para>When used with the <command>reboot</command> command, indicate to the system's firmware to
+          reboot into the firmware setup interface. Note that this functionality is not available on all
+          systems.</para>
         </listitem>
       </varlistentry>
 
@@ -2217,10 +2242,10 @@ Jan 12 10:46:45 example.com bluetoothd[8900]: gatt-time-server: Input/output err
         <term><option>--boot-loader-menu=</option></term>
 
         <listitem>
-          <para>When used with the <command>reboot</command> command, indicate to the system's boot loader to show the
-          boot loader menu on the following boot. Takes a time value as parameter — indicating the menu timeout. Pass
-          zero in order to disable the menu timeout. Note that not all boot loaders support this
-          functionality.</para>
+          <para>When used with the <command>reboot</command> command, indicate to the system's boot loader to
+          show the boot loader menu on the following boot. Takes a time value as parameter — indicating the
+          menu timeout. Pass zero in order to disable the menu timeout. Note that not all boot loaders
+          support this functionality.</para>
         </listitem>
       </varlistentry>
 
@@ -2228,10 +2253,10 @@ Jan 12 10:46:45 example.com bluetoothd[8900]: gatt-time-server: Input/output err
         <term><option>--boot-loader-entry=</option></term>
 
         <listitem>
-          <para>When used with the <command>reboot</command> command, indicate to the system's boot loader to boot into
-          a specific boot loader entry on the following boot. Takes a boot loader entry identifier as argument, or
-          <literal>help</literal> in order to list available entries. Note that not all boot loaders support this
-          functionality.</para>
+          <para>When used with the <command>reboot</command> command, indicate to the system's boot loader to
+          boot into a specific boot loader entry on the following boot. Takes a boot loader entry identifier
+          as argument, or <literal>help</literal> in order to list available entries. Note that not all boot
+          loaders support this functionality.</para>
         </listitem>
       </varlistentry>
 
index 139f79fa6b7d56ef9450315b48053ea09397812c..5169bbbd0f60d4e3019b1ffc4ed9ca9b02d7d8c7 100644 (file)
@@ -73,8 +73,8 @@
       <citerefentry><refentrytitle>systemctl</refentrytitle><manvolnum>1</manvolnum></citerefentry> for
       details.</para></listitem>
 
-      <listitem><para>An EFI variable set by the boot loader informs the OS about the ESP partition used
-      during boot. This is then used to automatically mount the correct ESP partition to
+      <listitem><para>An EFI variable set by the boot loader informs the OS about the EFI System Partition used
+      during boot. This is then used to automatically mount the correct EFI System Partition to
       <filename>/efi/</filename> or <filename>/boot/</filename> during OS runtime. See
       <citerefentry><refentrytitle>systemd-gpt-auto-generator</refentrytitle><manvolnum>8</manvolnum></citerefentry>
       for details.</para></listitem>
     <title>EFI Variables</title>
 
     <para>The following EFI variables are defined, set and read by <command>systemd-boot</command>, under the vendor
-    UUID <literal>4a67b082-0a4c-41cf-b6c7-440b29bb8c4</literal>, for communication between the OS and the boot
+    UUID <literal>4a67b082-0a4c-41cf-b6c7-440b29bb8c4f</literal>, for communication between the OS and the boot
     loader:</para>
 
     <variablelist class='efi-variables'>
index d5719bc463586c8ad2ffc479382a80c7e66f97e0..c6d6c5bd6ca30ea8f87aea0b011dd2dabc527021 100644 (file)
@@ -84,7 +84,7 @@
         <term><option>--pkcs11-token-uri=</option><replaceable>URI</replaceable></term>
 
         <listitem><para>Enroll a PKCS#11 security token or smartcard (e.g. a YubiKey). Expects a PKCS#11
-        smart card URI referring to the token. Alternatively the special value <literal>auto</literal> may
+        smartcard URI referring to the token. Alternatively the special value <literal>auto</literal> may
         be specified, in order to automatically determine the URI of a currently plugged in security token
         (of which there must be exactly one). The special value <literal>list</literal> may be used to
         enumerate all suitable PKCS#11 tokens currently plugged in. The security token must contain an RSA
index 87cf98c31a0142c2d774b6ea575f860ebdb47a89..66d829941b89e7ace7228614b975be1275bb33bf 100644 (file)
       <varlistentry>
         <term><literal>passwd.shell.root</literal></term>
 
-        <listitem><para>Specifies the shell binary to use for the specified account when creating it.
+        <listitem><para>Specifies the shell binary to use for the specified account.
         Equivalent to the credential of the same name defined for the
         <citerefentry><refentrytitle>systemd-sysusers.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>
         service.</para></listitem>
index 4a21540c702d0c1a9988da8f3551c71d84c7c483..798faa59c830cf0366ef78768fcc8fa286194694 100644 (file)
             <entry><filename>/</filename></entry>
             <entry>On Itanium systems, the first Itanium root partition on the disk the EFI ESP is located on is mounted to the root directory <filename>/</filename>.</entry>
           </row>
+          <row>
+            <entry>77055800-792c-4f94-b39a-98c91b762bb6</entry>
+            <entry><filename>Root Partition (LoongArch 64)</filename></entry>
+            <entry><filename>/</filename></entry>
+            <entry>On LoongArch 64-bit systems, the first LoongArch 64-bit root partition on the disk the EFI ESP is located on is mounted to the root directory <filename>/</filename>.</entry>
+          </row>
           <row>
             <entry>60d5a7fe-8e7d-435c-b714-3dd8162144e1</entry>
             <entry><filename>Root Partition (RISCV-V 32)</filename></entry>
index a9c52d842c54bb9c16c800a35090832ededa14cb..177fe892a650c89a239118393eb8cebedfd11a59 100644 (file)
@@ -90,7 +90,7 @@
 
       <varlistentry>
         <term><option>--image=<replaceable>path</replaceable></option></term>
-        <listitem><para>Takes a path to a device node or refular file as argument. This is similar to
+        <listitem><para>Takes a path to a device node or regular file as argument. This is similar to
         <option>--root=</option> as described above, but operates on a disk image instead of a directory
         tree.</para></listitem>
       </varlistentry>
index e929d32f62b6a90987acca2817628fafbf1afa74..3623ef015a19c1fd468360f70ebd17205b5c7f47 100644 (file)
@@ -1375,12 +1375,12 @@ After=sys-subsystem-net-devices-ens1.device</programlisting>
         </orderedlist>
 
         <para>The combination of the three operations above ensures that it is possible to log into the
-        host's user account inside the container as if it was local to the container. The user is only mapped
-        transiently, while the container is running and the mapping itself does not result in persistent
-        changes to the container (except maybe for generated log messages at login time, and similar). Note
-        that in particular the UID/GID assignment in the container is not made persistently. If the user is
-        mapped transiently, it is best to not allow the user to make persistent changes to the container. If
-        the user leaves files or directories owned by the user, and those UIDs/GIDs are recycled during later
+        container using the same account information as on the host. The user is only mapped transiently,
+        while the container is running, and the mapping itself does not result in persistent changes to the
+        container (except maybe for log messages generated at login time, and similar). Note that in
+        particular the UID/GID assignment in the container is not made persistently. If the user is mapped
+        transiently, it is best to not allow the user to make persistent changes to the container. If the
+        user leaves files or directories owned by the user, and those UIDs/GIDs are reused during later
         container invocations (possibly with a different <option>--bind-user=</option> mapping), those files
         and directories will be accessible to the "new" user.</para>
 
@@ -1581,9 +1581,9 @@ After=sys-subsystem-net-devices-ens1.device</programlisting>
         -b</programlisting>
 
         <para>The above command line will invoke the specified image file <filename>image.raw</filename> in
-        volatile mode, i.e with an empty <filename>/etc/</filename> and <filename>/var/</filename>, so that
-        the container's payload recognizes this as first boot condition, and will invoke
-        <filename>systemd-firstboot.service</filename>, which then read the two passed credentials to
+        volatile mode, i.e. with empty <filename>/etc/</filename> and <filename>/var/</filename>.  The
+        container payload will recognize this as a first boot, and will invoke
+        <filename>systemd-firstboot.service</filename>, which then reads the two passed credentials to
         configure the system's initial locale and root password.</para>
         </listitem>
         </varlistentry>
index 23906f2663aa56700cf9ef77a8682c321ae41112..61f2c5ca9e59747a4946b48a3cfe75049a23a190 100644 (file)
@@ -35,8 +35,8 @@
     <para>Most of <command>systemd-portabled</command>'s functionality is accessible through the
     <citerefentry><refentrytitle>portablectl</refentrytitle><manvolnum>1</manvolnum></citerefentry> command.</para>
 
-    <para>See the <ulink url="https://systemd.io/PORTABLE_SERVICES">Portable
-    Services Documentation</ulink> for details about the concepts this service implements.</para>
+    <para>See <ulink url="https://systemd.io/PORTABLE_SERVICES">Portable Services</ulink> for details about
+    the concepts this service implements.</para>
   </refsect1>
 
   <refsect1>
index 661e36b00b2023fde0b21b1396074dc26056f999..34c1257ab007778688f303a3f2872ae3b6fbd6d8 100644 (file)
       turn. Additionally, lookup of single-label names via unicast DNS may be enabled with the
       <varname>ResolveUnicastSingleLabel=yes</varname> setting. The details of which servers are queried and
       how the final reply is chosen are described below. Note that this means that address queries for
-      single-label names are never sent out to remote DNS servers by default, and resoulution is only
+      single-label names are never sent out to remote DNS servers by default, and resolution is only
       possible if search domains are defined.</para></listitem>
 
       <listitem><para>Multi-label names with the domain suffix <literal>.local</literal> are resolved using
@@ -275,7 +275,7 @@ search foobar.com barbar.com
       fragility in both directions: a valid global name could be obscured by a local name, and resolution of
       a relative local name could suddenly break when a new top-level domain is created, or when a new
       subdomain of a top-level domain in registered. Resolving any given name as either relative or absolute
-      avoids this ambiguity.)</para></footnote></para></listitem>
+      avoids this ambiguity.</para></footnote></para></listitem>
 
       <listitem><para>This resolver has a notion of the special <literal>.local</literal> domain used for
       MulticastDNS, and will not route queries with that suffix to unicast DNS servers unless explicitly
index ad6a401c7a221ab4edd5241e44823c7bce8d5178..f8a9f47539f1c817c50a8546bf66b423774d051b 100644 (file)
@@ -46,7 +46,7 @@
     operating system tree. When one or more system extension images are activated, their
     <filename>/usr/</filename> and <filename>/opt/</filename> hierarchies are combined via
     <literal>overlayfs</literal> with the same hierarchies of the host OS, and the host
-    <filename>/usr/</filename> and <filename>/opt</filename> overmounted with it ("merging"). When they are
+    <filename>/usr/</filename> and <filename>/opt/</filename> overmounted with it ("merging"). When they are
     deactivated, the mount point is disassembled — again revealing the unmodified original host version of
     the hierarchy ("unmerging"). Merging thus makes the extension's resources suddenly appear below the
     <filename>/usr/</filename> and <filename>/opt/</filename> hierarchies as if they were included in the
@@ -71,7 +71,7 @@
     <orderedlist>
       <listitem><para>Plain directories or btrfs subvolumes containing the OS tree</para></listitem>
       <listitem><para>Disk images with a GPT disk label, following the <ulink
-      url="https://systemd.io/DISCOVERABLE_PARTITIONS">Discoverable Partition Specification</ulink></para></listitem>
+      url="https://systemd.io/DISCOVERABLE_PARTITIONS">Discoverable Partitions Specification</ulink></para></listitem>
       <listitem><para>Disk images lacking a partition table, with a naked Linux file system (e.g. squashfs or ext4)</para></listitem>
     </orderedlist>
 
     <title>Uses</title>
 
     <para>The primary use case for system images are immutable environments where debugging and development
-    tools shall optionally be made available, but not included in the immutable base OS image itself
-    (e.g. <filename>strace</filename> and <filename>gdb</filename> shall be an optionally installable
-    addition in order to make debugging/development easier). System extension images should not be
-    misunderstood as a generic software packaging framework, as no dependency scheme is available: system
-    extensions should carry all files they need themselves, except for those already shipped in the
-    underlying host system image. Typically, system extension images are built at the same time as the base
-    OS image — within the same build system.</para>
+    tools shall optionally be made available, but not included in the immutable base OS image itself (e.g.
+    <citerefentry project='man-pages'><refentrytitle>strace</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+    and
+    <citerefentry project='man-pages'><refentrytitle>gdb</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+    shall be an optionally installable addition in order to make debugging/development easier). System
+    extension images should not be misunderstood as a generic software packaging framework, as no dependency
+    scheme is available: system extensions should carry all files they need themselves, except for those
+    already shipped in the underlying host system image. Typically, system extension images are built at the
+    same time as the base OS image — within the same build system.</para>
 
     <para>Another use case for the system extension concept is temporarily overriding OS supplied resources
     with newer ones, for example to install a locally compiled development version of some low-level
index c11dd461439ae6f9f5f641e32f253322dc4bed0b..5824e01e0c826207d00be9ba999fe2acc5f09111 100644 (file)
         names in status messages (e.g. <literal>systemd-journald.service</literal>), instead of the longer
         and more informative descriptions set with <varname>Description=</varname> (e.g. <literal>Journal
         Logging Service</literal>). If <option>combined</option>, the system manager will use both unit names
-        and descriptions in status messages (e.g. <literal>systemdmd-jouranld.service - Journal Logging
+        and descriptions in status messages (e.g. <literal>systemd-journald.service - Journal Logging
         Service</literal>).</para>
 
         <para>See
index fbbc740040fb6c1c18b68f5beda37eb2e41975e7..9d8b62c45248aa0af0eebcb02f65d3c3af1cb26c 100644 (file)
     JSON user/group records from classic UNIX/glibc NSS user/group records in order to provide full backwards
     compatibility. It may also pick up statically defined JSON user/group records from drop-in files in
     <filename>/etc/userdb/</filename>, <filename>/run/userdb/</filename>,
-    <filename>/run/host/userdb/</filename> and <filename>/use/lib/userdb/</filename>.</para>
+    <filename>/run/host/userdb/</filename> and <filename>/usr/lib/userdb/</filename>.</para>
 
     <para>Most of <command>systemd-userdbd</command>'s functionality is accessible through the
     <citerefentry><refentrytitle>userdbctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>
     command.</para>
 
     <para>The user and group records this service provides access to follow the <ulink
-    url="https://systemd.io/USER_RECORD">JSON User Record</ulink> and <ulink
+    url="https://systemd.io/USER_RECORD">JSON User Records</ulink> and <ulink
     url="https://systemd.io/GROUP_RECORD">JSON Group Record</ulink> definitions. This service implements the
     <ulink url="https://systemd.io/USER_GROUP_API">User/Group Record Lookup API via Varlink</ulink>, and
     multiplexes access other services implementing this API, too. It is thus both server and client of this
index c9554b087aebb35bfd0a33670f459e36d83c5c93..70f08374e228a963297640ee6c1a04d8c88f7727 100644 (file)
     <para>At early boot and when the system manager configuration is reloaded kernel command line configuration for
     integrity protected block devices is translated into <filename>systemd-veritysetup@.service</filename> units by
     <citerefentry><refentrytitle>systemd-veritysetup-generator</refentrytitle><manvolnum>8</manvolnum></citerefentry>.</para>
+
+    <para><filename>systemd-veritysetup@.service</filename> calls <command>systemd-veritysetup</command>.</para>
+  </refsect1>
+
+  <refsect1>
+    <title>Commands</title>
+
+    <para>The following commands are understood by <command>systemd-veritysetup</command>:</para>
+
+    <variablelist>
+      <varlistentry>
+        <term>
+          <option>attach</option>
+          <replaceable>volume</replaceable>
+          <replaceable>datadevice</replaceable>
+          <replaceable>hashdevice</replaceable>
+          <replaceable>roothash</replaceable>
+          [<replaceable>option</replaceable>...]
+        </term>
+
+        <listitem><para>Create a block device <replaceable>volume</replaceable> using
+        <replaceable>datadevice</replaceable> and <replaceable>hashdevice</replaceable> as the backing
+        devices. <replaceable>roothash</replaceable> forms the root of the tree of hashes stored on
+        <replaceable>hashdevice</replaceable>. See
+        <ulink url="https://www.kernel.org/doc/html/latest/admin-guide/device-mapper/verity.html">
+          Kernel dm-verity</ulink> documentation for details.
+        </para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term>
+          <option>detach</option>
+          <replaceable>volume</replaceable>
+        </term>
+
+        <listitem><para>Detach (destroy) the block device
+        <replaceable>volume</replaceable>.</para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term>
+          <option>help</option>
+        </term>
+
+        <listitem><para>Print short information about command syntax.</para></listitem>
+      </varlistentry>
+    </variablelist>
   </refsect1>
 
   <refsect1>
index ccb1567900ef290e4c028827ed4501d1bfaf8db6..008cbe9af1d4edd596c443bdfd1b5ed4964fb35f 100644 (file)
         <para>This option is supported only for disk images that contain a single file system, without an
         enveloping partition table. Images that contain a GPT partition table should instead include both
         root file system and matching Verity data in the same image, implementing the <ulink
-        url="https://systemd.io/DISCOVERABLE_PARTITIONS">Discoverable Partition Specification</ulink>.</para>
+        url="https://systemd.io/DISCOVERABLE_PARTITIONS">Discoverable Partitions Specification</ulink>.</para>
 
         <xi:include href="system-only.xml" xpointer="singular"/></listitem>
       </varlistentry>
         <term><varname>ExtensionImages=</varname></term>
 
         <listitem><para>This setting is similar to <varname>MountImages=</varname> in that it mounts a file
-        system hierarchy from a block device node or loopback file, but instead of providing a destination path,
-        an overlay will be set up. This option expects a whitespace separated list of mount definitions. Each
-        definition consists of a source path, optionally followed by a colon and a list of mount options.</para>
+        system hierarchy from a block device node or loopback file, but instead of providing a destination
+        path, an overlay will be set up. This option expects a whitespace separated list of mount
+        definitions. Each definition consists of a source path, optionally followed by a colon and a list of
+        mount options.</para>
 
         <para>A read-only OverlayFS will be set up on top of <filename>/usr/</filename> and
-        <filename>/opt/</filename> hierarchies from the root. The order in which the images are listed
-        will determine the order in which the overlay is laid down: images specified first to last will result
-        in overlayfs layers bottom to top.</para>
+        <filename>/opt/</filename> hierarchies. The order in which the images are listed will determine the
+        order in which the overlay is laid down: images specified first to last will result in overlayfs
+        layers bottom to top.</para>
 
         <para>Mount options may be defined as a single comma-separated list of options, in which case they
         will be implicitly applied to the root partition on the image, or a series of colon-separated tuples
@@ -2304,7 +2305,7 @@ SystemCallErrorNumber=EPERM</programlisting>
 
         <listitem><para>Sets environment variables for executed processes. Each line is unquoted using the
         rules described in "Quoting" section in
-        <citerefentry><refentrytitle>systemd.syntax</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+        <citerefentry><refentrytitle>systemd.syntax</refentrytitle><manvolnum>7</manvolnum></citerefentry>
         and becomes a list of variable assignments. If you need to assign a value containing spaces or the
         equals sign to a variable, put quotes around the whole assignment. Variable expansion is not
         performed inside the strings and the <literal>$</literal> character has no special meaning. Specifier
index 1093e2e0b84f7c058261e904668fb60e42717a2e..ee4356ac3d66b6f14e021eb49168db1b70dd9059 100644 (file)
         <term><varname>MTUBytes=</varname></term>
         <listitem>
           <para>The maximum transmission unit in bytes to set for the
-          device. The usual suffixes K, M, G, are supported and are
+          device. The usual suffixes K, M, G are supported and are
           understood to the base of 1024.</para>
         </listitem>
       </varlistentry>
         <term><varname>BitsPerSecond=</varname></term>
         <listitem>
           <para>The speed to set for the device, the value is rounded
-          down to the nearest Mbps. The usual suffixes K, M, G, are
+          down to the nearest Mbps. The usual suffixes K, M, G are
           supported and are understood to the base of 1000.</para>
         </listitem>
       </varlistentry>
         <term><varname>GenericSegmentOffloadMaxBytes=</varname></term>
         <listitem>
           <para>Specifies the maximum size of a Generic Segment Offload (GSO) packet the
-          device should accept. The usual suffixes K, M, G, are supported and are
+          device should accept. The usual suffixes K, M, G are supported and are
           understood to the base of 1024. An unsigned integer in the range 1…65536.
           Defaults to unset.</para>
         </listitem>
       <varlistentry>
         <term><varname>GenericSegmentOffloadMaxSegments=</varname></term>
         <listitem>
-          <para>Specifies the maximum number of Generic Segment Offload (GSO) segments the device should
-          accept.  An unsigned integer in the range 1…65535. Defaults to unset.</para>
+          <para>Specifies the maximum number of Generic Segment Offload (GSO) segments the device should
+          accept. An unsigned integer in the range 1…65535. Defaults to unset.</para>
         </listitem>
       </varlistentry>
 
index 1d1d71786fa78c1427a34c865f6157e50f1dcb32..f62b4cb4004356dc0e4b7b75b444b20621878889 100644 (file)
         <term><varname>DefaultPVID=</varname></term>
         <listitem>
           <para>This specifies the default port VLAN ID of a newly attached bridge port.
-          Set this to an integer in the range 1â\80\934094 or <literal>none</literal> to disable the PVID.</para>
+          Set this to an integer in the range 1â\80¦4094 or <literal>none</literal> to disable the PVID.</para>
         </listitem>
       </varlistentry>
       <varlistentry>
       <varlistentry>
         <term><varname>Id=</varname></term>
         <listitem>
-          <para>The VLAN ID to use. An integer in the range 0â\80\934094.
+          <para>The VLAN ID to use. An integer in the range 0â\80¦4094.
           This setting is compulsory.</para>
         </listitem>
       </varlistentry>
         <term><varname>TTL=</varname></term>
         <listitem>
           <para>A fixed Time To Live N on Virtual eXtensible Local Area Network packets.
-          Takes <literal>inherit</literal> or a number in the range 0â\80\93255. 0 is a special
+          Takes <literal>inherit</literal> or a number in the range 0â\80¦255. 0 is a special
           value meaning inherit the inner protocol's TTL value. <literal>inherit</literal>
           means that it will inherit the outer protocol's TTL value.</para>
         </listitem>
       <varlistentry>
         <term><varname>TunnelId=</varname></term>
         <listitem>
-          <para>Specifies the tunnel identifier. Takes an number in the range 1â\80\934294967295. The value used
+          <para>Specifies the tunnel identifier. Takes an number in the range 1â\80¦4294967295. The value used
           must match the <literal>PeerTunnelId=</literal> value being used at the peer. This setting is
           compulsory.</para>
         </listitem>
       <varlistentry>
         <term><varname>SessionId=</varname></term>
         <listitem>
-          <para>Specifies the session identifier. Takes an number in the range 1â\80\934294967295. The value used
+          <para>Specifies the session identifier. Takes an number in the range 1â\80¦4294967295. The value used
           must match the <literal>SessionId=</literal> value being used at the peer. This setting is
           compulsory.</para>
         </listitem>
       <varlistentry>
         <term><varname>PeerSessionId=</varname></term>
         <listitem>
-          <para>Specifies the peer session identifier. Takes an number in the range 1â\80\934294967295.
+          <para>Specifies the peer session identifier. Takes an number in the range 1â\80¦4294967295.
           The value used must match the <literal>PeerSessionId=</literal> value being used at the peer.
           This setting is compulsory.</para>
         </listitem>
         <term><varname>TTL=</varname></term>
         <listitem>
           <para>A fixed Time To Live N on tunneled packets. N is a
-          number in the range 1â\80\93255. 0 is a special value meaning that
+          number in the range 1â\80¦255. 0 is a special value meaning that
           packets inherit the TTL value. The default value for IPv4
           tunnels is 0 (inherit). The default value for IPv6 tunnels is
           64.</para>
           It is only used for IPv6 tunnels.
           A flow label of zero is used to indicate packets that have
           not been labeled.
-          It can be configured to a value in the range 0â\80\930xFFFFF, or be
+          It can be configured to a value in the range 0â\80¦0xFFFFF, or be
           set to <literal>inherit</literal>, in which case the original flowlabel is used.</para>
         </listitem>
       </varlistentry>
           <para>Sets a comma-separated list of IP (v4 or v6) addresses with CIDR masks
           from which this peer is allowed to send incoming traffic and to
           which outgoing traffic for this peer is directed.</para>
+
           <para>The catch-all 0.0.0.0/0 may be specified for matching all IPv4 addresses,
           and ::/0 may be specified for matching all IPv6 addresses.</para>
-          <para>Note that this only affects "routing inside the network interface itself",
-          as in, which wireguard peer packets with a specific destination address are sent to,
-          and what source addresses are accepted from which peer.</para>
-          <para>To cause packets to be sent via wireguard in first place, a route needs
-          to be added, as well - either in the <literal>[Routes]</literal> section on the
-          <literal>.network</literal> matching the wireguard interface, or outside of networkd.
-          </para>
+
+          <para>Note that this only affects <emphasis>routing inside the network interface itself</emphasis>,
+          i.e. the packets that pass through the tunnel itself. To cause packets to be sent via the tunnel in
+          the first place, an appropriate route needs to be added as well — either in the
+          <literal>[Routes]</literal> section on the <literal>.network</literal> matching the wireguard
+          interface, or externally to <filename>systemd-networkd</filename>.</para>
         </listitem>
       </varlistentry>
       <varlistentry>
         <term><varname>AdUserPortKey=</varname></term>
         <listitem>
           <para>Specifies the 802.3ad user defined portion of the port key. Takes a number in the range
-          0â\80\931023.</para>
+          0â\80¦1023.</para>
         </listitem>
       </varlistentry>
 
 
   <refsect1>
     <title>[BatmanAdvanced] Section Options</title>
-    <para>The [BatmanAdvanced] section only applies for
-    netdevs of kind <literal>batadv</literal> and accepts the
-    following keys:</para>
+
+    <para>The [BatmanAdvanced] section only applies for netdevs of kind <literal>batadv</literal> and accepts
+    the following keys:</para>
 
     <variablelist class='network-directives'>
       <varlistentry>
index 77d7ce5c18b15d8aec92c374dcb03f2f5813a646..b8bb8aedf4625a720a03a274f260fef263253e51 100644 (file)
@@ -998,14 +998,6 @@ IPv6Token=prefixstable:2002:da8:1::</programlisting></para>
           </para>
         </listitem>
       </varlistentry>
-      <varlistentry>
-        <term><varname>Xfrm=</varname></term>
-        <listitem>
-          <para>The name of the xfrm to create on the link. See
-            <citerefentry><refentrytitle>systemd.netdev</refentrytitle><manvolnum>5</manvolnum></citerefentry>.
-            This option may be specified more than once.</para>
-        </listitem>
-      </varlistentry>
       <varlistentry>
         <term><varname>KeepConfiguration=</varname></term>
         <listitem>
@@ -1431,7 +1423,7 @@ IPv6Token=prefixstable:2002:da8:1::</programlisting></para>
           <term><varname>Metric=</varname></term>
           <listitem>
             <para>The metric of the route. Takes an unsigned integer in the range 0…4294967295.
-            Defaluts to unset, and the kernel's default will be used.</para>
+            Defaults to unset, and the kernel's default will be used.</para>
           </listitem>
         </varlistentry>
         <varlistentry>
@@ -1623,9 +1615,10 @@ IPv6Token=prefixstable:2002:da8:1::</programlisting></para>
           <term><varname>SendHostname=</varname></term>
           <listitem>
             <para>When true (the default), the machine's hostname (or the value specified with
-            <varname>Hostname=</varname> below) will be sent to the DHCP server. Note that the hostname must
-            consist only of 7-bit ASCII lower-case characters and no spaces or dots, and be formatted as a
-            valid DNS domain name. Otherwise, the hostname is not sent even if this option is true.</para>
+            <varname>Hostname=</varname>, described below) will be sent to the DHCP server. Note that the
+            hostname must consist only of 7-bit ASCII lower-case characters and no spaces or dots, and be
+            formatted as a valid DNS domain name. Otherwise, the hostname is not sent even if this option is
+            true.</para>
           </listitem>
         </varlistentry>
 
@@ -1919,8 +1912,8 @@ IPv6Token=prefixstable:2002:da8:1::</programlisting></para>
           <term><varname>FallbackLeaseLifetimeSec=</varname></term>
           <listitem>
             <para>Allows to set DHCPv4 lease lifetime when DHCPv4 server does not send the lease lifetime.
-            Takes one of <literal>forever</literal> or <literal>infinity</literal> means that the address
-            never expires. Defaults to unset.</para>
+            Takes one of <literal>forever</literal> or <literal>infinity</literal>. The latter means that the
+            address never expires. Defaults to unset.</para>
           </listitem>
         </varlistentry>
 
@@ -1986,7 +1979,7 @@ IPv6Token=prefixstable:2002:da8:1::</programlisting></para>
             DHCP server. After a new IP is received, the DHCPv4 client performs IPv4 Duplicate Address
             Detection. If duplicate use is detected, the DHCPv4 client rejects the IP by sending a
             <constant>DHCPDECLINE</constant> packet and tries to obtain an IP address again. See <ulink
-            url="https://tools.ietf.org/html/rfc5227">RFC 5224</ulink>. Defaults to
+            url="https://tools.ietf.org/html/rfc5227">RFC 5227</ulink>. Defaults to
             <literal>unset</literal>.</para>
           </listitem>
         </varlistentry>
@@ -2347,9 +2340,9 @@ IPv6Token=prefixstable:2002:da8:1::</programlisting></para>
       <varlistentry>
         <term><varname>ServerAddress=</varname></term>
         <listitem><para>Specifies server address for the DHCP server. Takes an IPv4 address with prefix
-        length, e.g., <literal>192.168.0.1/24</literal>. This setting may be useful when the link which
-        DHCP server running on has multiple static addresses. When unset, one of static addresses in
-        the link will be automatically selected. Defaults to unset.</para></listitem>
+        length, for example <literal>192.168.0.1/24</literal>. This setting may be useful when the link on
+        which the DHCP server is running has multiple static addresses. When unset, one of static addresses
+        in the link will be automatically selected. Defaults to unset.</para></listitem>
       </varlistentry>
 
       <varlistentry>
@@ -2529,23 +2522,22 @@ IPv6Token=prefixstable:2002:da8:1::</programlisting></para>
 
   <refsect1>
     <title>[DHCPServerStaticLease] Section Options</title>
-    <para>The <literal>[DHCPServerStaticLease]</literal> section configures a static DHCP lease to
-    assign a pre-set IPv4 address to a specific device based on its MAC address. This section can be
-    specified multiple times.</para>
+    <para>The <literal>[DHCPServerStaticLease]</literal> section configures a static DHCP lease to assign a
+    fixed IPv4 address to a specific device based on its MAC address. This section can be specified multiple
+    times.</para>
 
     <variablelist class='network-directives'>
       <varlistentry>
         <term><varname>MACAddress=</varname></term>
 
-        <listitem><para>The hardware address of a device which should be assigned IPv4 address
-        specified in <varname>Address=</varname>. This key is mandatory.</para></listitem>
+        <listitem><para>The hardware address of a device to match. This key is mandatory.</para></listitem>
       </varlistentry>
 
       <varlistentry>
         <term><varname>Address=</varname></term>
 
-        <listitem><para>IPv4 address that should be assigned to a device with a hardware address
-        specified in <varname>MACAddress=</varname>. This key is mandatory.</para></listitem>
+        <listitem><para>The IPv4 address that should be assigned to the device that was matched with
+        <varname>MACAddress=</varname>. This key is mandatory.</para></listitem>
       </varlistentry>
     </variablelist>
   </refsect1>
index 7ba8e361b4214424dd8a3b1f924cd4de7a2bd323..dc0e2f9fd2141c9cfb58c59ecabd0efe9fe28392 100644 (file)
         capabilities (see
         <citerefentry project='man-pages'><refentrytitle>capabilities</refentrytitle><manvolnum>7</manvolnum></citerefentry>
         for details). The <varname>AmbientCapability=</varname> setting
-        specifies capability which will be passed to to started program
+        specifies capability which will be passed to the started program
         in the inheritable and ambient capability sets. This will grant
         these capabilities to this process. This setting correspond to
         the <option>--ambient-capability=</option> command line switch.
index 64333a3216f0830a4850c123026b515996356426..9e6db28536b6dd5ebda9d53bf47dd12dab52950c 100644 (file)
@@ -207,7 +207,7 @@ disable *</programlisting>
       <citerefentry><refentrytitle>systemd-delta</refentrytitle><manvolnum>1</manvolnum></citerefentry>
     </para>
 
-    <para><citerefentry><refentrytitle>daemon</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+    <para><citerefentry><refentrytitle>daemon</refentrytitle><manvolnum>7</manvolnum></citerefentry>
     has a discussion of packaging scriptlets.</para>
 
     <para>Fedora page introducing the use of presets:
index 350bc5f8e5bca5054c2702ed046ab9bfbe2d65f4..884260a2159ce0e4a10062b31cda6772dc4a1bb9 100644 (file)
     <literal>\;</literal>.</para>
 
     <para>Each command line is unquoted using the rules described in "Quoting" section in
-    <citerefentry><refentrytitle>systemd.syntax</refentrytitle><manvolnum>5</manvolnum></citerefentry>. The
+    <citerefentry><refentrytitle>systemd.syntax</refentrytitle><manvolnum>7</manvolnum></citerefentry>. The
     first item becomes the command to execute, and the subsequent items the arguments.</para>
 
     <para>This syntax is inspired by shell syntax, but only the meta-characters and expansions
index 7fafbc1d4ccc7ceb95dba3c61806f07269d7e1b8..b6e4a2233c4552888f9ff4dba169999293c98513 100644 (file)
       <varlistentry>
         <term><varname>Upholds=</varname></term>
 
-        <listitem><para>Configures dependencies similar to <varname>Wants=</varname>, but as long a this unit
+        <listitem><para>Configures dependencies similar to <varname>Wants=</varname>, but as long as this unit
         is up, all units listed in <varname>Upholds=</varname> are started whenever found to be inactive or
         failed, and no job is queued for them. While a <varname>Wants=</varname> dependency on another unit
         has a one-time effect when this units started, a <varname>Upholds=</varname> dependency on it has a
         <varlistentry>
           <term><varname>ConditionControlGroupController=</varname></term>
 
-          <listitem><para>Check whether given cgroup controllers (eg. <literal>cpu</literal>) are available
+          <listitem><para>Check whether given cgroup controllers (e.g. <literal>cpu</literal>) are available
           for use on the system or whether the legacy v1 cgroup or the modern v2 cgroup hierarchy is used.
           </para>
 
index cd50cd426585904ecc28e3fff75a4c6c0aea9512..468edfb2d3953e73caa06e428536f83401952f48 100644 (file)
@@ -74,8 +74,8 @@
     configuration files, whose syntax and basic set of options is
     described in
     <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
-    however some are created automatically from other configuration,
-    dynamically from system state or programmatically at runtime.
+    however some are created automatically from other configuration
+    files, dynamically from system state or programmatically at runtime.
     Units may be "active" (meaning started, bound, plugged in, …,
     depending on the unit type, see below), or "inactive" (meaning
     stopped, unbound, unplugged, …), as well as in the process of
         for --user instances).</para></listitem>
       </varlistentry>
 
+      <varlistentry>
+        <term><constant>SIGRTMIN+25</constant></term>
+
+        <listitem><para>Upon receiving this signal the systemd manager will reexecute itself. This
+        is mostly equivalent to <command>systemctl daemon-reexec</command> except that it will be
+        done asynchronously.</para>
+
+        <para>The systemd system manager treats this signal the same way as
+        <constant>SIGTERM</constant>.</para></listitem>
+      </varlistentry>
+
       <varlistentry>
         <term><constant>SIGRTMIN+26</constant></term>
 
index 261de5902d57d691078577f77f9ebd4315dba45d..305033b672e606d6e6d36d122bdf8ed94cfdfb46 100644 (file)
@@ -550,6 +550,7 @@ w- /proc/sys/vm/swappiness - - - - 10</programlisting></para>
 
     <refsect2>
       <title>Age</title>
+
       <para>The date field, when set, is used to decide what files to
       delete when cleaning. If a file or directory is older than the
       current time minus the age field, it is deleted. The field
@@ -582,10 +583,9 @@ w- /proc/sys/vm/swappiness - - - - 10</programlisting></para>
       and <varname>X</varname>. If omitted or set to
       <literal>-</literal>, no automatic clean-up is done.</para>
 
-      <para>If the age field starts with a tilde character
-      <literal>~</literal>, the clean-up is only applied to files and
-      directories one level inside the directory specified, but not
-      the files and directories immediately inside it.</para>
+      <para>If the age field starts with a tilde character <literal>~</literal>, clean-up is only applied to
+      files and directories one level inside the directory specified, but not the files and directories
+      immediately inside it.</para>
 
       <para>The age of a file system entry is determined from its last
       modification timestamp (mtime), its last access timestamp (atime),
@@ -595,30 +595,25 @@ w- /proc/sys/vm/swappiness - - - - 10</programlisting></para>
       the age field. To restrict the deletion based on particular type
       of file timestamps, the age-by argument can be used.</para>
 
-      <para>The age-by argument, when (optionally) specified along
-      with age will check if the file system entry has aged by the
-      type of file timestamp(s) provided. It can be specified by
-      prefixing the age argument with a set of file timestamp types
-      followed by a colon character <literal>:</literal>, i.e.,
-      <literal><replaceable>age-by</replaceable>:<replaceable>cleanup-age</replaceable></literal>.
-      The argument can be a set of:
-      <constant>a</constant> (<constant>A</constant> for directories),
-      <constant>b</constant> (<constant>B</constant> for directories),
-      <constant>c</constant> (<constant>C</constant> for directories; ignored by default), or
-      <constant>m</constant> (<constant>M</constant> for directories),
-      indicating access, creation, last status change, and last
-      modification times of a file system entry respectively. See
-      <citerefentry project='man-pages'><refentrytitle>statx</refentrytitle><manvolnum>2</manvolnum></citerefentry>
-      file timestamp fields for more details.</para>
-
-      <para>If unspecified, the age-by field defaults to
-      <constant>abcmABM</constant>,
-      i.e., by default all file timestamps are taken into consideration,
-      with the exception of the last status change timestamp (ctime) for
-      directories. This is because the aging logic itself will alter the
-      ctime whenever it deletes a file inside it. To ensure that running
-      the aging logic does not feed back into the next iteration of it,
-      ctime for directories is ignored by default.</para>
+      <para>The age-by argument overrides the timestamp types to be used for the age check. It can be
+      specified by prefixing the age argument with a sequence of characters to specify the timestamp types
+      and a colon (<literal>:</literal>):
+      <literal><replaceable>age-by</replaceable>...:<replaceable>cleanup-age</replaceable></literal>.  The
+      argument can consist of <constant>a</constant> (<constant>A</constant> for directories),
+      <constant>b</constant> (<constant>B</constant> for directories), <constant>c</constant>
+      (<constant>C</constant> for directories), or <constant>m</constant> (<constant>M</constant> for
+      directories). Those respectively indicate access, creation, last status change, and last modification
+      time of a file system entry. The lower-case letter signifies that the given timestamp type should be
+      considered for files, while the upper-case letter signifies that the given timestamp type should be
+      considered for directories. See <citerefentry
+      project='man-pages'><refentrytitle>statx</refentrytitle><manvolnum>2</manvolnum></citerefentry> file
+      timestamp fields for more details about timestamp types.</para>
+
+      <para>If not specified, the age-by field defaults to <constant>abcmABM</constant>, i.e. by default all
+      file timestamps are taken into consideration, with the exception of the last status change timestamp
+      (ctime) for directories. This is because the aging logic itself will alter the ctime whenever it
+      deletes a file inside it. To ensure that running the aging logic does not feed back into the next
+      iteration of itself, ctime for directories is ignored by default.</para>
 
       <para>For example:<programlisting>
 # Files created and modified, and directories accessed more than
index 0871306b202b6aff3f4f77cd613a122394dde4e4..611c425b795cc94bb7b1ef5f82ea73a3bbd00214 100644 (file)
@@ -42,7 +42,7 @@
     url="https://systemd.io/USER_GROUP_API">User/Group Record Lookup API via Varlink</ulink>, and may also
     pick up drop-in JSON user and group records from <filename>/etc/userdb/</filename>,
     <filename>/run/userdb/</filename>, <filename>/run/host/userdb/</filename>,
-    <filename>/use/lib/userdb/</filename>.</para>
+    <filename>/usr/lib/userdb/</filename>.</para>
   </refsect1>
 
   <refsect1>
 
         <listitem><para>Controls whether to include user/group lookups in the output that are defined using
         drop-in files in <filename>/etc/userdb/</filename>, <filename>/run/userdb/</filename>,
-        <filename>/run/host/userdb/</filename>, <filename>/use/lib/userdb/</filename>. If
+        <filename>/run/host/userdb/</filename>, <filename>/usr/lib/userdb/</filename>. If
         <option>--with-dropin=no</option> is used these records are suppressed. If
         <option>--with-dropin=yes</option> is specified such users/groups are included in the output (which
         is the default).</para></listitem>
         <citerefentry><refentrytitle>systemd-userdbd.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>
         and picks up JSON user/group records from <filename>/etc/userdb/</filename>,
         <filename>/run/userdb/</filename>, <filename>/run/host/userdb/</filename>,
-        <filename>/use/lib/userdb/</filename>.</para></listitem>
+        <filename>/usr/lib/userdb/</filename>.</para></listitem>
       </varlistentry>
 
     </variablelist>
index 366f2c5607a215292b80dc5bbc1d6c482d287d90..e08a7662a7fb89d927ef2a67e0a011b4350e6fc1 100644 (file)
@@ -10,7 +10,7 @@ project('systemd', 'c',
                 'localstatedir=/var',
                 'warning_level=2',
         ],
-        meson_version : '>= 0.46',
+        meson_version : '>= 0.53.2',
        )
 
 libsystemd_version = '0.32.0'
@@ -91,6 +91,7 @@ sysvinit_path = get_option('sysvinit-path')
 sysvrcnd_path = get_option('sysvrcnd-path')
 conf.set10('HAVE_SYSV_COMPAT', sysvinit_path != '' and sysvrcnd_path != '',
            description : 'SysV init scripts and rcN.d links are supported')
+conf.set10('CREATE_LOG_DIRS', get_option('create-log-dirs'))
 
 if get_option('hibernate') and not get_option('initrd')
         error('hibernate depends on initrd')
@@ -100,9 +101,9 @@ conf.set10('BUMP_PROC_SYS_FS_FILE_MAX', get_option('bump-proc-sys-fs-file-max'))
 conf.set10('BUMP_PROC_SYS_FS_NR_OPEN',  get_option('bump-proc-sys-fs-nr-open'))
 conf.set('HIGH_RLIMIT_NOFILE',          512*1024)
 
-# join_paths ignores the preceding arguments if an absolute component is
-# encountered, so this should canonicalize various paths when they are
-# absolute or relative.
+# Meson ignores the preceding arguments when joining paths if an absolute
+# component is encountered, so this should canonicalize various paths when they
+# are absolute or relative.
 prefixdir = get_option('prefix')
 if not prefixdir.startswith('/')
         error('Prefix is not absolute: "@0@"'.format(prefixdir))
@@ -112,100 +113,105 @@ if prefixdir != rootprefixdir and rootprefixdir != '/' and not prefixdir.strip('
                 rootprefixdir, prefixdir))
 endif
 
-bindir = join_paths(prefixdir, get_option('bindir'))
-libdir = join_paths(prefixdir, get_option('libdir'))
-sysconfdir = join_paths(prefixdir, get_option('sysconfdir'))
-includedir = join_paths(prefixdir, get_option('includedir'))
-datadir = join_paths(prefixdir, get_option('datadir'))
-localstatedir = join_paths('/', get_option('localstatedir'))
+bindir = prefixdir / get_option('bindir')
+libdir = prefixdir / get_option('libdir')
+sysconfdir = prefixdir / get_option('sysconfdir')
+includedir = prefixdir / get_option('includedir')
+datadir = prefixdir / get_option('datadir')
+localstatedir = '/' / get_option('localstatedir')
 
-rootbindir = join_paths(rootprefixdir, 'bin')
-rootsbindir = join_paths(rootprefixdir, split_bin ? 'sbin' : 'bin')
-rootlibexecdir = join_paths(rootprefixdir, 'lib/systemd')
+rootbindir = rootprefixdir / 'bin'
+rootsbindir = rootprefixdir / (split_bin ? 'sbin' : 'bin')
+rootlibexecdir = rootprefixdir / 'lib/systemd'
 
 rootlibdir = get_option('rootlibdir')
 if rootlibdir == ''
-        rootlibdir = join_paths(rootprefixdir, libdir.split('/')[-1])
+        rootlibdir = rootprefixdir / libdir.split('/')[-1]
 endif
 
 install_sysconfdir = get_option('install-sysconfdir') != 'false'
 install_sysconfdir_samples = get_option('install-sysconfdir') == 'true'
 # Dirs of external packages
-pkgconfigdatadir = get_option('pkgconfigdatadir') == '' ? join_paths(datadir, 'pkgconfig') : get_option('pkgconfigdatadir')
-pkgconfiglibdir = get_option('pkgconfiglibdir') == '' ? join_paths(libdir, 'pkgconfig') : get_option('pkgconfiglibdir')
-polkitpolicydir = join_paths(datadir, 'polkit-1/actions')
-polkitrulesdir = join_paths(datadir, 'polkit-1/rules.d')
-polkitpkladir = join_paths(localstatedir, 'lib/polkit-1/localauthority/10-vendor.d')
-xinitrcdir = get_option('xinitrcdir') == '' ? join_paths(sysconfdir, 'X11/xinit/xinitrc.d') : get_option('xinitrcdir')
+pkgconfigdatadir = get_option('pkgconfigdatadir') != '' ? get_option('pkgconfigdatadir') : datadir / 'pkgconfig'
+pkgconfiglibdir = get_option('pkgconfiglibdir') != '' ? get_option('pkgconfiglibdir') : libdir / 'pkgconfig'
+polkitpolicydir = datadir / 'polkit-1/actions'
+polkitrulesdir = datadir / 'polkit-1/rules.d'
+polkitpkladir = localstatedir / 'lib/polkit-1/localauthority/10-vendor.d'
+xinitrcdir = get_option('xinitrcdir') != '' ? get_option('xinitrcdir') : sysconfdir / 'X11/xinit/xinitrc.d'
 rpmmacrosdir = get_option('rpmmacrosdir')
 if rpmmacrosdir != 'no'
-        rpmmacrosdir = join_paths(prefixdir, rpmmacrosdir)
+        rpmmacrosdir = prefixdir / rpmmacrosdir
 endif
-modprobedir = join_paths(rootprefixdir, 'lib/modprobe.d')
+modprobedir = rootprefixdir / 'lib/modprobe.d'
 
 # Our own paths
-pkgdatadir = join_paths(datadir, 'systemd')
-environmentdir = join_paths(prefixdir, 'lib/environment.d')
-pkgsysconfdir = join_paths(sysconfdir, 'systemd')
-userunitdir = join_paths(prefixdir, 'lib/systemd/user')
-userpresetdir = join_paths(prefixdir, 'lib/systemd/user-preset')
-tmpfilesdir = join_paths(prefixdir, 'lib/tmpfiles.d')
-sysusersdir = join_paths(prefixdir, 'lib/sysusers.d')
-sysctldir = join_paths(prefixdir, 'lib/sysctl.d')
-binfmtdir = join_paths(prefixdir, 'lib/binfmt.d')
-modulesloaddir = join_paths(prefixdir, 'lib/modules-load.d')
-networkdir = join_paths(rootprefixdir, 'lib/systemd/network')
-pkgincludedir = join_paths(includedir, 'systemd')
-systemgeneratordir = join_paths(rootlibexecdir, 'system-generators')
-usergeneratordir = join_paths(prefixdir, 'lib/systemd/user-generators')
-systemenvgeneratordir = join_paths(prefixdir, 'lib/systemd/system-environment-generators')
-userenvgeneratordir = join_paths(prefixdir, 'lib/systemd/user-environment-generators')
-systemshutdowndir = join_paths(rootlibexecdir, 'system-shutdown')
-systemsleepdir = join_paths(rootlibexecdir, 'system-sleep')
-systemunitdir = join_paths(rootprefixdir, 'lib/systemd/system')
-systempresetdir = join_paths(rootprefixdir, 'lib/systemd/system-preset')
-udevlibexecdir = join_paths(rootprefixdir, 'lib/udev')
-udevrulesdir = join_paths(udevlibexecdir, 'rules.d')
-udevhwdbdir = join_paths(udevlibexecdir, 'hwdb.d')
-catalogdir = join_paths(prefixdir, 'lib/systemd/catalog')
-kernelinstalldir = join_paths(prefixdir, 'lib/kernel/install.d')
-factorydir = join_paths(datadir, 'factory')
-bootlibdir = join_paths(prefixdir, 'lib/systemd/boot/efi')
-testsdir = join_paths(prefixdir, 'lib/systemd/tests')
-systemdstatedir = join_paths(localstatedir, 'lib/systemd')
-catalogstatedir = join_paths(systemdstatedir, 'catalog')
-randomseeddir = join_paths(localstatedir, 'lib/systemd')
-profiledir = join_paths(rootlibexecdir, 'portable', 'profile')
-ntpservicelistdir = join_paths(rootprefixdir, 'lib/systemd/ntp-units.d')
+pkgdatadir = datadir / 'systemd'
+environmentdir = prefixdir / 'lib/environment.d'
+pkgsysconfdir = sysconfdir / 'systemd'
+userunitdir = prefixdir / 'lib/systemd/user'
+userpresetdir = prefixdir / 'lib/systemd/user-preset'
+tmpfilesdir = prefixdir / 'lib/tmpfiles.d'
+sysusersdir = prefixdir / 'lib/sysusers.d'
+sysctldir = prefixdir / 'lib/sysctl.d'
+binfmtdir = prefixdir / 'lib/binfmt.d'
+modulesloaddir = prefixdir / 'lib/modules-load.d'
+networkdir = rootprefixdir / 'lib/systemd/network'
+pkgincludedir = includedir / 'systemd'
+systemgeneratordir = rootlibexecdir / 'system-generators'
+usergeneratordir = prefixdir / 'lib/systemd/user-generators'
+systemenvgeneratordir = prefixdir / 'lib/systemd/system-environment-generators'
+userenvgeneratordir = prefixdir / 'lib/systemd/user-environment-generators'
+systemshutdowndir = rootlibexecdir / 'system-shutdown'
+systemsleepdir = rootlibexecdir / 'system-sleep'
+systemunitdir = rootprefixdir / 'lib/systemd/system'
+systempresetdir = rootprefixdir / 'lib/systemd/system-preset'
+udevlibexecdir = rootprefixdir / 'lib/udev'
+udevrulesdir = udevlibexecdir / 'rules.d'
+udevhwdbdir = udevlibexecdir / 'hwdb.d'
+catalogdir = prefixdir / 'lib/systemd/catalog'
+kernelinstalldir = prefixdir / 'lib/kernel/install.d'
+factorydir = datadir / 'factory'
+bootlibdir = prefixdir / 'lib/systemd/boot/efi'
+testsdir = prefixdir / 'lib/systemd/tests'
+systemdstatedir = localstatedir / 'lib/systemd'
+catalogstatedir = systemdstatedir / 'catalog'
+randomseeddir = localstatedir / 'lib/systemd'
+profiledir = rootlibexecdir / 'portable' / 'profile'
+ntpservicelistdir = rootprefixdir / 'lib/systemd/ntp-units.d'
 
 docdir = get_option('docdir')
 if docdir == ''
-        docdir = join_paths(datadir, 'doc/systemd')
+        docdir = datadir / 'doc/systemd'
 endif
 
 dbuspolicydir = get_option('dbuspolicydir')
 if dbuspolicydir == ''
-        dbuspolicydir = join_paths(datadir, 'dbus-1/system.d')
+        dbuspolicydir = datadir / 'dbus-1/system.d'
 endif
 
 dbussessionservicedir = get_option('dbussessionservicedir')
 if dbussessionservicedir == ''
-        dbussessionservicedir = join_paths(datadir, 'dbus-1/services')
+        dbussessionservicedir = datadir / 'dbus-1/services'
 endif
 
 dbussystemservicedir = get_option('dbussystemservicedir')
 if dbussystemservicedir == ''
-        dbussystemservicedir = join_paths(datadir, 'dbus-1/system-services')
+        dbussystemservicedir = datadir / 'dbus-1/system-services'
 endif
 
 pamlibdir = get_option('pamlibdir')
 if pamlibdir == ''
-        pamlibdir = join_paths(rootlibdir, 'security')
+        pamlibdir = rootlibdir / 'security'
 endif
 
 pamconfdir = get_option('pamconfdir')
 if pamconfdir == ''
-        pamconfdir = join_paths(prefixdir, 'lib/pam.d')
+        pamconfdir = prefixdir / 'lib/pam.d'
+endif
+
+libcryptsetup_plugins_dir = get_option('libcryptsetup-plugins-dir')
+if libcryptsetup_plugins_dir == ''
+        libcryptsetup_plugins_dir = rootlibdir / 'cryptsetup'
 endif
 
 memory_accounting_default = get_option('memory-accounting-default')
@@ -213,18 +219,19 @@ status_unit_format_default = get_option('status-unit-format-default')
 
 conf.set_quoted('BINFMT_DIR',                                 binfmtdir)
 conf.set_quoted('BOOTLIBDIR',                                 bootlibdir)
-conf.set_quoted('CATALOG_DATABASE',                           join_paths(catalogstatedir, 'database'))
+conf.set_quoted('CATALOG_DATABASE',                           catalogstatedir / 'database')
 conf.set_quoted('CERTIFICATE_ROOT',                           get_option('certificate-root'))
-conf.set_quoted('DOCUMENT_ROOT',                              join_paths(pkgdatadir, 'gatewayd'))
+conf.set_quoted('DOC_DIR',                                    docdir)
+conf.set_quoted('DOCUMENT_ROOT',                              pkgdatadir / 'gatewayd')
 conf.set_quoted('ENVIRONMENT_DIR',                            environmentdir)
 conf.set_quoted('INCLUDE_DIR',                                includedir)
 conf.set_quoted('LIBDIR',                                     libdir)
 conf.set_quoted('MODPROBE_DIR',                               modprobedir)
 conf.set_quoted('MODULESLOAD_DIR',                            modulesloaddir)
 conf.set_quoted('PKGSYSCONFDIR',                              pkgsysconfdir)
-conf.set_quoted('POLKIT_AGENT_BINARY_PATH',                   join_paths(bindir, 'pkttyagent'))
+conf.set_quoted('POLKIT_AGENT_BINARY_PATH',                   bindir / 'pkttyagent')
 conf.set_quoted('PREFIX',                                     prefixdir)
-conf.set_quoted('RANDOM_SEED',                                join_paths(randomseeddir, 'random-seed'))
+conf.set_quoted('RANDOM_SEED',                                randomseeddir / 'random-seed')
 conf.set_quoted('RANDOM_SEED_DIR',                            randomseeddir)
 conf.set_quoted('RC_LOCAL_PATH',                              get_option('rc-local'))
 conf.set_quoted('ROOTBINDIR',                                 rootbindir)
@@ -234,28 +241,29 @@ conf.set_quoted('ROOTPREFIX',                                 rootprefixdir)
 conf.set_quoted('ROOTPREFIX_NOSLASH',                         rootprefixdir_noslash)
 conf.set_quoted('SYSCONF_DIR',                                sysconfdir)
 conf.set_quoted('SYSCTL_DIR',                                 sysctldir)
-conf.set_quoted('SYSTEMCTL_BINARY_PATH',                      join_paths(rootbindir, 'systemctl'))
-conf.set_quoted('SYSTEMD_BINARY_PATH',                        join_paths(rootlibexecdir, 'systemd'))
+conf.set_quoted('SYSTEMCTL_BINARY_PATH',                      rootbindir / 'systemctl')
+conf.set_quoted('SYSTEMD_BINARY_PATH',                        rootlibexecdir / 'systemd')
 conf.set_quoted('SYSTEMD_CATALOG_DIR',                        catalogdir)
-conf.set_quoted('SYSTEMD_CGROUPS_AGENT_PATH',                 join_paths(rootlibexecdir, 'systemd-cgroups-agent'))
-conf.set_quoted('SYSTEMD_CRYPTSETUP_PATH',                    join_paths(rootlibexecdir, 'systemd-cryptsetup'))
-conf.set_quoted('SYSTEMD_EXPORT_PATH',                        join_paths(rootlibexecdir, 'systemd-export'))
-conf.set_quoted('SYSTEMD_FSCK_PATH',                          join_paths(rootlibexecdir, 'systemd-fsck'))
-conf.set_quoted('SYSTEMD_GROWFS_PATH',                        join_paths(rootlibexecdir, 'systemd-growfs'))
-conf.set_quoted('SYSTEMD_HOMEWORK_PATH',                      join_paths(rootlibexecdir, 'systemd-homework'))
-conf.set_quoted('SYSTEMD_IMPORT_FS_PATH',                     join_paths(rootlibexecdir, 'systemd-import-fs'))
-conf.set_quoted('SYSTEMD_IMPORT_PATH',                        join_paths(rootlibexecdir, 'systemd-import'))
-conf.set_quoted('SYSTEMD_KBD_MODEL_MAP',                      join_paths(pkgdatadir, 'kbd-model-map'))
-conf.set_quoted('SYSTEMD_LANGUAGE_FALLBACK_MAP',              join_paths(pkgdatadir, 'language-fallback-map'))
-conf.set_quoted('SYSTEMD_MAKEFS_PATH',                        join_paths(rootlibexecdir, 'systemd-makefs'))
-conf.set_quoted('SYSTEMD_PULL_PATH',                          join_paths(rootlibexecdir, 'systemd-pull'))
-conf.set_quoted('SYSTEMD_SHUTDOWN_BINARY_PATH',               join_paths(rootlibexecdir, 'systemd-shutdown'))
-conf.set_quoted('SYSTEMD_STDIO_BRIDGE_BINARY_PATH',           join_paths(bindir, 'systemd-stdio-bridge'))
-conf.set_quoted('SYSTEMD_TEST_DATA',                          join_paths(testsdir, 'testdata'))
-conf.set_quoted('SYSTEMD_TTY_ASK_PASSWORD_AGENT_BINARY_PATH', join_paths(rootbindir, 'systemd-tty-ask-password-agent'))
-conf.set_quoted('SYSTEMD_USERWORK_PATH',                      join_paths(rootlibexecdir, 'systemd-userwork'))
-conf.set_quoted('SYSTEMD_VERITYSETUP_PATH',                   join_paths(rootlibexecdir, 'systemd-veritysetup'))
-conf.set_quoted('SYSTEM_CONFIG_UNIT_DIR',                     join_paths(pkgsysconfdir, 'system'))
+conf.set_quoted('SYSTEMD_CGROUPS_AGENT_PATH',                 rootlibexecdir / 'systemd-cgroups-agent')
+conf.set_quoted('SYSTEMD_CRYPTSETUP_PATH',                    rootlibexecdir / 'systemd-cryptsetup')
+conf.set_quoted('SYSTEMD_EXPORT_PATH',                        rootlibexecdir / 'systemd-export')
+conf.set_quoted('SYSTEMD_FSCK_PATH',                          rootlibexecdir / 'systemd-fsck')
+conf.set_quoted('SYSTEMD_GROWFS_PATH',                        rootlibexecdir / 'systemd-growfs')
+conf.set_quoted('SYSTEMD_HOMEWORK_PATH',                      rootlibexecdir / 'systemd-homework')
+conf.set_quoted('SYSTEMD_IMPORT_FS_PATH',                     rootlibexecdir / 'systemd-import-fs')
+conf.set_quoted('SYSTEMD_IMPORT_PATH',                        rootlibexecdir / 'systemd-import')
+conf.set_quoted('SYSTEMD_KBD_MODEL_MAP',                      pkgdatadir / 'kbd-model-map')
+conf.set_quoted('SYSTEMD_LANGUAGE_FALLBACK_MAP',              pkgdatadir / 'language-fallback-map')
+conf.set_quoted('SYSTEMD_MAKEFS_PATH',                        rootlibexecdir / 'systemd-makefs')
+conf.set_quoted('SYSTEMD_PULL_PATH',                          rootlibexecdir / 'systemd-pull')
+conf.set_quoted('SYSTEMD_SHUTDOWN_BINARY_PATH',               rootlibexecdir / 'systemd-shutdown')
+conf.set_quoted('SYSTEMD_STDIO_BRIDGE_BINARY_PATH',           bindir / 'systemd-stdio-bridge')
+conf.set_quoted('SYSTEMD_TEST_DATA',                          testsdir / 'testdata')
+conf.set_quoted('SYSTEMD_TTY_ASK_PASSWORD_AGENT_BINARY_PATH', rootbindir / 'systemd-tty-ask-password-agent')
+conf.set_quoted('SYSTEMD_UPDATE_HELPER_PATH',                 rootlibexecdir / 'systemd-update-helper')
+conf.set_quoted('SYSTEMD_USERWORK_PATH',                      rootlibexecdir / 'systemd-userwork')
+conf.set_quoted('SYSTEMD_VERITYSETUP_PATH',                   rootlibexecdir / 'systemd-veritysetup')
+conf.set_quoted('SYSTEM_CONFIG_UNIT_DIR',                     pkgsysconfdir / 'system')
 conf.set_quoted('SYSTEM_DATA_UNIT_DIR',                       systemunitdir)
 conf.set_quoted('SYSTEM_ENV_GENERATOR_DIR',                   systemenvgeneratordir)
 conf.set_quoted('SYSTEM_GENERATOR_DIR',                       systemgeneratordir)
@@ -269,15 +277,17 @@ conf.set_quoted('TMPFILES_DIR',                               tmpfilesdir)
 conf.set_quoted('UDEVLIBEXECDIR',                             udevlibexecdir)
 conf.set_quoted('UDEV_HWDB_DIR',                              udevhwdbdir)
 conf.set_quoted('UDEV_RULES_DIR',                             udevrulesdir)
-conf.set_quoted('USER_CONFIG_UNIT_DIR',                       join_paths(pkgsysconfdir, 'user'))
+conf.set_quoted('UPDATE_HELPER_USER_TIMEOUT',                 get_option('update-helper-user-timeout'))
+conf.set_quoted('USER_CONFIG_UNIT_DIR',                       pkgsysconfdir / 'user')
 conf.set_quoted('USER_DATA_UNIT_DIR',                         userunitdir)
 conf.set_quoted('USER_ENV_GENERATOR_DIR',                     userenvgeneratordir)
 conf.set_quoted('USER_GENERATOR_DIR',                         usergeneratordir)
-conf.set_quoted('USER_KEYRING_PATH',                          join_paths(pkgsysconfdir, 'import-pubring.gpg'))
+conf.set_quoted('USER_KEYRING_PATH',                          pkgsysconfdir / 'import-pubring.gpg')
 conf.set_quoted('USER_PRESET_DIR',                            userpresetdir)
-conf.set_quoted('VENDOR_KEYRING_PATH',                        join_paths(rootlibexecdir, 'import-pubring.gpg'))
+conf.set_quoted('VENDOR_KEYRING_PATH',                        rootlibexecdir / 'import-pubring.gpg')
 
 conf.set('ANSI_OK_COLOR',                                     'ANSI_' + get_option('ok-color').underscorify().to_upper())
+conf.set10('ENABLE_URLIFY',                                   get_option('urlify'))
 conf.set10('ENABLE_FEXECVE',                                  get_option('fexecve'))
 conf.set10('MEMORY_ACCOUNTING_DEFAULT',                       memory_accounting_default)
 conf.set('STATUS_UNIT_FORMAT_DEFAULT',                        'STATUS_UNIT_FORMAT_' + status_unit_format_default.to_upper())
@@ -322,7 +332,6 @@ basic_disabled_warnings = [
         '-Wno-format-signedness',
         '-Wno-missing-field-initializers',
         '-Wno-unused-parameter',
-        '-Wno-unused-result',
 ]
 
 possible_common_cc_flags = [
@@ -366,8 +375,14 @@ if cc.get_id() == 'gcc' and (not '02'.contains(get_option('optimization')) or
         possible_common_cc_flags += '-Wno-maybe-uninitialized'
 endif
 
+# Disable -Wno-unused-result with gcc, see
+# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66425.
+if cc.get_id() == 'gcc'
+        possible_common_cc_flags += '-Wno-unused-result'
+endif
+
 # --as-needed and --no-undefined are provided by meson by default,
-# run mesonconf to see what is enabled
+# run 'meson configure' to see what is enabled
 possible_link_flags = [
         '-Wl,-z,relro',
         '-Wl,-z,now',
@@ -582,7 +597,7 @@ test_efi_create_disk_sh = find_program('test/test-efi-create-disk.sh')
 mkdir_p = 'mkdir -p $DESTDIR/@0@'
 splash_bmp = files('test/splash.bmp')
 
-# if -Dxxx-path option is found, use that. Otherwise, check in $PATH,
+# If -Dxxx-path option is found, use that. Otherwise, check in $PATH,
 # /usr/sbin, /sbin, and fall back to the default from middle column.
 progs = [['quotaon',    '/usr/sbin/quotaon'    ],
          ['quotacheck', '/usr/sbin/quotacheck' ],
@@ -707,6 +722,8 @@ if time_epoch == -1
 endif
 conf.set('TIME_EPOCH', time_epoch)
 
+conf.set('CLOCK_VALID_RANGE_USEC_MAX', get_option('clock-valid-range-usec-max'))
+
 foreach tuple : [['system-alloc-uid-min', 'SYS_UID_MIN', 1],  # Also see login.defs(5).
                  ['system-uid-max',       'SYS_UID_MAX', 999],
                  ['system-alloc-gid-min', 'SYS_GID_MIN', 1],
@@ -894,10 +911,6 @@ conf.set10('LOG_TRACE', get_option('log-trace'))
 default_user_path = get_option('user-path')
 if default_user_path != ''
         conf.set_quoted('DEFAULT_USER_PATH', default_user_path)
-        default_user_path_display = default_user_path
-else
-        # meson 0.49 fails when ?: is used in .format()
-        default_user_path_display = '(same as system services)'
 endif
 
 
@@ -937,9 +950,11 @@ if want_bpf_framework == 'false'
 else
         clang = find_program('clang', required : bpf_framework_required)
         llvm_strip = find_program('llvm-strip', required : bpf_framework_required)
-        # Debian installs this in /usr/sbin/ which is not in $PATH
-        # FIXME: use the 'dirs' parameter once we bump Meson version to >= 0.53
+
+        # Debian installs this in /usr/sbin/ which is not in $PATH.
+        # We check for 'bpftool' first, honouring $PATH, and in /usr/sbin/ for Debian.
         bpftool = find_program('bpftool', '/usr/sbin/bpftool', required : bpf_framework_required)
+
         bpf_arches = ['x86_64']
         deps_found = libbpf.found() and clang.found() and llvm_strip.found() and bpftool.found()
         # Can build BPF program from source code in restricted C
@@ -1096,10 +1111,16 @@ endif
 conf.set10('HAVE_MICROHTTPD', have)
 
 want_libcryptsetup = get_option('libcryptsetup')
+want_libcryptsetup_plugins = get_option('libcryptsetup-plugins')
+
+if want_libcryptsetup_plugins == 'true' and want_libcryptsetup == 'false'
+        error('libcryptsetup-plugins can not be requested without libcryptsetup')
+endif
+
 if want_libcryptsetup != 'false' and not skip_deps
         libcryptsetup = dependency('libcryptsetup',
-                                   version : '>= 2.0.1',
-                                   required : want_libcryptsetup == 'true')
+                                   version : want_libcryptsetup_plugins == 'true' ? '>= 2.4.0' : '>= 2.0.1',
+                                   required : want_libcryptsetup == 'true' or want_libcryptsetup_plugins == 'true')
         have = libcryptsetup.found()
 
         conf.set10('HAVE_CRYPT_SET_METADATA_SIZE',
@@ -1114,6 +1135,14 @@ else
 endif
 conf.set10('HAVE_LIBCRYPTSETUP', have)
 
+if want_libcryptsetup_plugins != 'false' and not skip_deps
+        have = (cc.has_function('crypt_activate_by_token_pin', dependencies : libcryptsetup) and
+                cc.has_function('crypt_token_external_path', dependencies : libcryptsetup))
+else
+        have = false
+endif
+conf.set10('HAVE_LIBCRYPTSETUP_PLUGINS', have)
+
 want_libcurl = get_option('libcurl')
 if want_libcurl != 'false' and not skip_deps
         libcurl = dependency('libcurl',
@@ -1666,6 +1695,7 @@ subdir('src/libsystemd')
 subdir('src/shared')
 subdir('src/udev')
 subdir('src/libudev')
+subdir('src/cryptsetup/cryptsetup-tokens')
 
 libsystemd = shared_library(
         'systemd',
@@ -1742,6 +1772,22 @@ install_libudev_static = static_library(
         c_args : static_libudev_pic ? [] : ['-fno-PIC'],
         pic : static_libudev_pic)
 
+if conf.get('HAVE_LIBCRYPTSETUP_PLUGINS') == 1
+        if conf.get('HAVE_TPM2') == 1
+                cryptsetup_token_systemd_tpm2 = shared_library(
+                        'cryptsetup-token-systemd-tpm2',
+                        link_args : ['-shared',
+                                     '-Wl,--version-script=' + cryptsetup_token_sym_path],
+                        dependencies : libshared_deps + [libcryptsetup, versiondep],
+                        link_with : [libshared],
+                        link_whole : [cryptsetup_token_systemd_tpm2_static],
+                        link_depends : cryptsetup_token_sym,
+                        install_rpath : rootlibexecdir,
+                        install : true,
+                        install_dir : libcryptsetup_plugins_dir)
+        endif
+endif
+
 ############################################################
 
 # systemd-analyze requires 'libcore'
@@ -1813,7 +1859,7 @@ foreach tuple : [['myhostname', 'ENABLE_NSS_MYHOSTNAME'],
                 module = tuple[0]
 
                 sym = 'src/nss-@0@/nss-@0@.sym'.format(module)
-                version_script_arg = join_paths(project_source_root, sym)
+                version_script_arg = project_source_root / sym
 
                 sources = ['src/nss-@0@/nss-@0@.c'.format(module)]
                 if tuple.length() > 2
@@ -1878,8 +1924,8 @@ executable(
         install_dir : rootlibexecdir)
 
 meson.add_install_script(meson_make_symlink,
-                         join_paths(rootlibexecdir, 'systemd'),
-                         join_paths(rootsbindir, 'init'))
+                         rootlibexecdir / 'systemd',
+                         rootsbindir / 'init')
 
 public_programs += executable(
         'systemd-analyze',
@@ -1984,8 +2030,8 @@ if conf.get('ENABLE_ENVIRONMENT_D') == 1
                 install_dir : userenvgeneratordir)
 
         meson.add_install_script(meson_make_symlink,
-                                 join_paths(sysconfdir, 'environment'),
-                                 join_paths(environmentdir, '99-environment.conf'))
+                                 sysconfdir / 'environment',
+                                 environmentdir / '99-environment.conf')
 endif
 
 if conf.get('ENABLE_HIBERNATE') == 1
@@ -2056,12 +2102,12 @@ if conf.get('ENABLE_RESOLVE') == 1
                 install : true)
 
         meson.add_install_script(meson_make_symlink,
-                                 join_paths(bindir, 'resolvectl'),
-                                 join_paths(rootsbindir, 'resolvconf'))
+                                 bindir / 'resolvectl',
+                                 rootsbindir / 'resolvconf')
 
         meson.add_install_script(meson_make_symlink,
-                                 join_paths(bindir, 'resolvectl'),
-                                 join_paths(bindir, 'systemd-resolve'))
+                                 bindir / 'resolvectl',
+                                 bindir / 'systemd-resolve')
 endif
 
 if conf.get('ENABLE_LOGIND') == 1
@@ -2100,7 +2146,7 @@ if conf.get('ENABLE_LOGIND') == 1
                 install_dir : rootbindir)
 
         if conf.get('HAVE_PAM') == 1
-                version_script_arg = join_paths(project_source_root, pam_systemd_sym)
+                version_script_arg = project_source_root / pam_systemd_sym
                 pam_systemd = shared_library(
                         'pam_systemd',
                         pam_systemd_c,
@@ -2318,7 +2364,7 @@ if conf.get('ENABLE_HOMED') == 1
                 install_dir : rootbindir)
 
         if conf.get('HAVE_PAM') == 1
-                version_script_arg = join_paths(project_source_root, pam_systemd_home_sym)
+                version_script_arg = project_source_root / pam_systemd_home_sym
                 pam_systemd = shared_library(
                         'pam_systemd_home',
                         pam_systemd_home_c,
@@ -2341,13 +2387,13 @@ endif
 foreach alias : (['halt', 'poweroff', 'reboot', 'shutdown'] +
                  (conf.get('HAVE_SYSV_COMPAT') == 1 ? ['runlevel', 'telinit'] : []))
         meson.add_install_script(meson_make_symlink,
-                                 join_paths(rootbindir, 'systemctl'),
-                                 join_paths(rootsbindir, alias))
+                                 rootbindir / 'systemctl',
+                                 rootsbindir / alias)
 endforeach
 
 meson.add_install_script(meson_make_symlink,
-                         join_paths(rootbindir, 'udevadm'),
-                         join_paths(rootlibexecdir, 'systemd-udevd'))
+                         rootbindir / 'udevadm',
+                         rootlibexecdir / 'systemd-udevd')
 
 if conf.get('ENABLE_BACKLIGHT') == 1
         executable(
@@ -2784,7 +2830,7 @@ if conf.get('ENABLE_BINFMT') == 1
                                  mkdir_p.format(binfmtdir))
         if install_sysconfdir
                 meson.add_install_script('sh', '-c',
-                                         mkdir_p.format(join_paths(sysconfdir, 'binfmt.d')))
+                                         mkdir_p.format(sysconfdir / 'binfmt.d'))
         endif
 endif
 
@@ -3061,7 +3107,7 @@ public_programs += executable(
         install : true)
 
 meson.add_install_script(meson_make_symlink,
-                         'systemd-mount', join_paths(bindir, 'systemd-umount'))
+                         'systemd-mount', bindir / 'systemd-umount')
 
 public_programs += executable(
         'systemd-run',
@@ -3263,7 +3309,7 @@ if conf.get('HAVE_KMOD') == 1
                                  mkdir_p.format(modulesloaddir))
         if install_sysconfdir
                 meson.add_install_script('sh', '-c',
-                                         mkdir_p.format(join_paths(sysconfdir, 'modules-load.d')))
+                                         mkdir_p.format(sysconfdir / 'modules-load.d'))
         endif
 endif
 
@@ -3343,8 +3389,8 @@ custom_target(
         output : 'systemd-runtest.env',
         command : [sh, '-c',
                    '{ echo SYSTEMD_TEST_DATA=@0@; echo SYSTEMD_CATALOG_DIR=@1@; } >@OUTPUT@'.format(
-                           join_paths(project_source_root, 'test'),
-                           join_paths(project_build_root, 'catalog'))],
+                           project_source_root / 'test',
+                           project_build_root / 'catalog')],
         build_by_default : true)
 
 test_cflags = ['-DTEST_CODE=1']
@@ -3386,7 +3432,7 @@ foreach tuple : tests
                         build_by_default : want_tests != 'false',
                         install_rpath : rootlibexecdir,
                         install : install_tests,
-                        install_dir : join_paths(testsdir, type))
+                        install_dir : testsdir / type)
 
                 if type == 'manual'
                         message('@0@ is a manual test'.format(name))
@@ -3502,16 +3548,13 @@ foreach tuple : fuzzers
                         if b == name
                                 test('@0@_@1@'.format(b, c),
                                      exe,
-                                     args : [join_paths(project_source_root, p)])
+                                     args : [project_source_root / p])
                         endif
                 endforeach
         endif
 endforeach
 
-run_target(
-        'fuzzers',
-        depends : fuzzer_exes,
-        command : ['true'])
+alias_target('fuzzers', fuzzer_exes)
 
 ############################################################
 
@@ -3564,8 +3607,8 @@ if get_option('mode') == 'developer' and want_tests != 'false' and jekyll.found(
         test('github-pages',
              jekyll,
              args : ['build',
-                     '--source', join_paths(project_source_root, 'docs'),
-                     '--destination', join_paths(project_build_root, '_site')])
+                     '--source', project_source_root / 'docs',
+                     '--destination', project_build_root / '_site'])
 endif
 
 ############################################################
@@ -3615,7 +3658,7 @@ foreach tuple : sanitizers
                                                 output : name,
                                                 depends : build,
                                                 command : [ln, '-fs',
-                                                           join_paths(build.full_path(), b),
+                                                           build.full_path() / b,
                                                            '@OUTPUT@'],
                                                 build_by_default : true)
                                 else
@@ -3630,7 +3673,7 @@ foreach tuple : sanitizers
                                      env : ['UBSAN_OPTIONS=print_stacktrace=1:print_summary=1:halt_on_error=1'],
                                      timeout : 60,
                                      args : [exe.full_path(),
-                                             join_paths(project_source_root, p)])
+                                             project_source_root / p])
                         endif
                 endforeach
         endif
@@ -3690,99 +3733,67 @@ run_target(
         depends : [man, libsystemd, libudev],
         command : [check_api_docs_sh, libsystemd.full_path(), libudev.full_path()])
 
-############################################################
-
-if dbus_docs.length() > 0
-        custom_target(
-                'update-dbus-docs',
-                output : 'update-dbus-docs',
-                command : [update_dbus_docs_py,
-                           '--build-dir=@0@'.format(project_build_root),
-                           '@INPUT@'],
-                input : dbus_docs)
-
-        if conf.get('BUILD_MODE_DEVELOPER') == 1
-                test('dbus-docs-fresh',
-                     update_dbus_docs_py,
-                     args : ['--build-dir=@0@'.format(project_build_root),
-                             '--test'] + dbus_docs)
-        endif
-endif
-
-custom_target(
-        'update-man-rules',
-        output : 'update-man-rules',
-        command : [sh, '-c',
-                   'cd @0@ && '.format(meson.build_root()) +
-                   'python3 @0@/tools/update-man-rules.py $(find @0@ -wholename "*/man/*.xml") >t && '.format(project_source_root) +
-                   'mv t @0@/man/rules/meson.build'.format(meson.current_source_dir())],
-        depends : custom_entities_ent)
+alias_target('update-dbus-docs', update_dbus_docs)
+alias_target('update-man-rules', update_man_rules)
 
 ############################################################
-watchdog_opt = service_watchdog == '' ? 'disabled' : service_watchdog
-
-status = [
-        '@0@ @1@'.format(meson.project_name(), meson.project_version()),
-
-        'build mode:                        @0@'.format(get_option('mode')),
-        'split /usr:                        @0@'.format(split_usr),
-        'split bin-sbin:                    @0@'.format(split_bin),
-        'prefix directory:                  @0@'.format(prefixdir),
-        'rootprefix directory:              @0@'.format(rootprefixdir),
-        'sysconf directory:                 @0@'.format(sysconfdir),
-        'include directory:                 @0@'.format(includedir),
-        'lib directory:                     @0@'.format(libdir),
-        'rootlib directory:                 @0@'.format(rootlibdir),
-        'SysV init scripts:                 @0@'.format(sysvinit_path),
-        'SysV rc?.d directories:            @0@'.format(sysvrcnd_path),
-        'PAM modules directory:             @0@'.format(pamlibdir),
-        'PAM configuration directory:       @0@'.format(pamconfdir),
-        'RPM macros directory:              @0@'.format(rpmmacrosdir),
-        'modprobe.d directory:              @0@'.format(modprobedir),
-        'D-Bus policy directory:            @0@'.format(dbuspolicydir),
-        'D-Bus session directory:           @0@'.format(dbussessionservicedir),
-        'D-Bus system directory:            @0@'.format(dbussystemservicedir),
-        'bash completions directory:        @0@'.format(bashcompletiondir),
-        'zsh completions directory:         @0@'.format(zshcompletiondir),
-        'extra start script:                @0@'.format(get_option('rc-local')),
-        'debug shell:                       @0@ @ @1@'.format(get_option('debug-shell'),
-                                                              get_option('debug-tty')),
-        'system UIDs:                       <=@0@ (alloc >=@1@)'.format(conf.get('SYSTEM_UID_MAX'),
-                                                                        conf.get('SYSTEM_ALLOC_UID_MIN')),
-        'system GIDs:                       <=@0@ (alloc >=@1@)'.format(conf.get('SYSTEM_GID_MAX'),
-                                                                        conf.get('SYSTEM_ALLOC_GID_MIN')),
-        'dynamic UIDs:                      @0@…@1@'.format(dynamic_uid_min, dynamic_uid_max),
-        'container UID bases:               @0@…@1@'.format(container_uid_base_min, container_uid_base_max),
-        'static UID/GID allocations:        @0@'.format(' '.join(static_ugids)),
-        '/dev/kvm access mode:              @0@'.format(get_option('dev-kvm-mode')),
-        'render group access mode:          @0@'.format(get_option('group-render-mode')),
-        'certificate root directory:        @0@'.format(get_option('certificate-root')),
-        'support URL:                       @0@'.format(support_url),
-        'nobody user name:                  @0@'.format(nobody_user),
-        'nobody group name:                 @0@'.format(nobody_group),
-        'fallback hostname:                 @0@'.format(get_option('fallback-hostname')),
-
-        'default DNSSEC mode:               @0@'.format(default_dnssec),
-        'default DNS-over-TLS mode:         @0@'.format(default_dns_over_tls),
-        'default mDNS mode:                 @0@'.format(default_mdns),
-        'default LLMNR mode:                @0@'.format(default_llmnr),
-        'default cgroup hierarchy:          @0@'.format(default_hierarchy),
-        'default net.naming-scheme setting: @0@'.format(default_net_naming_scheme),
-        'default KillUserProcesses setting: @0@'.format(kill_user_processes),
-        'default locale:                    @0@'.format(default_locale),
-        'default user $PATH:                @0@'.format(default_user_path_display),
-        'systemd service watchdog:          @0@'.format(watchdog_opt)]
-
-alt_dns_servers = '\n                                            '.join(dns_servers.split(' '))
-alt_ntp_servers = '\n                                            '.join(ntp_servers.split(' '))
-status += [
-        'default DNS servers:               @0@'.format(alt_dns_servers),
-        'default NTP servers:               @0@'.format(alt_ntp_servers)]
 
 alt_time_epoch = run_command('date', '-Is', '-u', '-d',
                              '@@0@'.format(time_epoch)).stdout().strip()
-status += [
-        'time epoch:                        @0@ (@1@)'.format(time_epoch, alt_time_epoch)]
+
+summary({
+        'build mode' :                      get_option('mode'),
+        'split /usr' :                      split_usr,
+        'split bin-sbin' :                  split_bin,
+        'prefix directory' :                prefixdir,
+        'rootprefix directory' :            rootprefixdir,
+        'sysconf directory' :               sysconfdir,
+        'include directory' :               includedir,
+        'lib directory' :                   libdir,
+        'rootlib directory' :               rootlibdir,
+        'SysV init scripts' :               sysvinit_path,
+        'SysV rc?.d directories' :          sysvrcnd_path,
+        'PAM modules directory' :           pamlibdir,
+        'PAM configuration directory' :     pamconfdir,
+        'libcryptsetup plugins directory' : libcryptsetup_plugins_dir,
+        'RPM macros directory' :            rpmmacrosdir,
+        'modprobe.d directory' :            modprobedir,
+        'D-Bus policy directory' :          dbuspolicydir,
+        'D-Bus session directory' :         dbussessionservicedir,
+        'D-Bus system directory' :          dbussystemservicedir,
+        'bash completions directory' :      bashcompletiondir,
+        'zsh completions directory' :       zshcompletiondir,
+        'extra start script' :              get_option('rc-local'),
+        'debug shell' :                     '@0@ @ @1@'.format(get_option('debug-shell'),
+                                                               get_option('debug-tty')),
+        'system UIDs' :                     '<=@0@ (alloc >=@1@)'.format(conf.get('SYSTEM_UID_MAX'),
+                                                                         conf.get('SYSTEM_ALLOC_UID_MIN')),
+        'system GIDs' :                     '<=@0@ (alloc >=@1@)'.format(conf.get('SYSTEM_GID_MAX'),
+                                                                         conf.get('SYSTEM_ALLOC_GID_MIN')),
+        'dynamic UIDs' :                    '@0@…@1@'.format(dynamic_uid_min, dynamic_uid_max),
+        'container UID bases' :             '@0@…@1@'.format(container_uid_base_min, container_uid_base_max),
+        'static UID/GID allocations' :      ' '.join(static_ugids),
+        '/dev/kvm access mode' :            get_option('dev-kvm-mode'),
+        'render group access mode' :        get_option('group-render-mode'),
+        'certificate root directory' :      get_option('certificate-root'),
+        'support URL' :                     support_url,
+        'nobody user name' :                nobody_user,
+        'nobody group name' :               nobody_group,
+        'fallback hostname' :               get_option('fallback-hostname'),
+        'default DNSSEC mode' :             default_dnssec,
+        'default DNS-over-TLS mode' :       default_dns_over_tls,
+        'default mDNS mode' :               default_mdns,
+        'default LLMNR mode' :              default_llmnr,
+        'default DNS servers' :             dns_servers.split(' '),
+        'default NTP servers' :             ntp_servers.split(' '),
+        'default cgroup hierarchy' :        default_hierarchy,
+        'default net.naming-scheme value' : default_net_naming_scheme,
+        'default KillUserProcesses value' : kill_user_processes,
+        'default locale' :                  default_locale,
+        'default user $PATH' :
+                default_user_path != '' ? default_user_path : '(same as system services)',
+        'systemd service watchdog' :        service_watchdog == '' ? 'disabled' : service_watchdog,
+        'time epoch' :                      '@0@ (@1@)'.format(time_epoch, alt_time_epoch)})
 
 # TODO:
 # CFLAGS:   ${OUR_CFLAGS} ${CFLAGS}
@@ -3790,15 +3801,17 @@ status += [
 # LDFLAGS:  ${OUR_LDFLAGS} ${LDFLAGS}
 
 if conf.get('ENABLE_EFI') == 1
-        status += 'efi arch:                          @0@'.format(efi_arch)
+        summary({'efi arch' : efi_arch},
+                section : 'Extensible Firmware Interface')
 
         if have_gnu_efi
-                status += [
-                        'EFI machine type:                  @0@'.format(EFI_MACHINE_TYPE_NAME),
-                        'EFI CC                             @0@'.format(' '.join(efi_cc)),
-                        'EFI lds:                           @0@'.format(efi_lds),
-                        'EFI crt0:                          @0@'.format(efi_crt0),
-                        'EFI include directory:             @0@'.format(efi_incdir)]
+                summary({
+                        'EFI machine type' :                EFI_MACHINE_TYPE_NAME,
+                        'EFI CC' :                          '@0@'.format(' '.join(efi_cc)),
+                        'EFI lds' :                         efi_lds,
+                        'EFI crt0' :                        efi_crt0,
+                        'EFI include directory' :           efi_incdir},
+                        section : 'Extensible Firmware Interface')
         endif
 endif
 
@@ -3821,6 +3834,7 @@ foreach tuple : [
         ['gnutls'],
         ['libbpf'],
         ['libcryptsetup'],
+        ['libcryptsetup-plugins'],
         ['libcurl'],
         ['libfdisk'],
         ['libfido2'],
@@ -3952,13 +3966,10 @@ else
         missing += 'DNS-over-TLS'
 endif
 
-status += [
-        '',
-        'enabled features: @0@'.format(', '.join(found)),
-        '',
-        'disabled features: @0@'.format(', '.join(missing)),
-        '']
-message('\n         '.join(status))
+summary({
+        'enabled' :  ', '.join(found),
+        'disabled' : ', '.join(missing)},
+        section : 'Features')
 
 if rootprefixdir != rootprefix_default
         warning('\n' +
index 163c8df87db56b90637221656d0ac01b13f3fbd7..110a471b6be47183f5b5c6396c7a73a835ce0e31 100644 (file)
@@ -182,10 +182,14 @@ option('xinitrcdir', type : 'string', value : '',
        description : 'directory for xinitrc files')
 option('rpmmacrosdir', type : 'string', value : 'lib/rpm/macros.d',
        description : 'directory for rpm macros ["no" disables]')
+option('update-helper-user-timeout', type : 'string', value : '15s',
+       description : 'how long to wait for user manager operations')
 option('pamlibdir', type : 'string',
        description : 'directory for PAM modules')
 option('pamconfdir', type : 'string',
        description : 'directory for PAM configuration ["no" disables]')
+option('libcryptsetup-plugins-dir', type : 'string',
+       description : 'directory for libcryptsetup plugins')
 option('docdir', type : 'string',
        description : 'documentation directory')
 option('install-sysconfdir', type : 'combo', choices : ['true', 'no-samples', 'false'], value : 'true',
@@ -204,6 +208,8 @@ option('status-unit-format-default', type : 'combo',
        description : 'use unit name or description in messages by default')
 option('time-epoch', type : 'integer', value : '-1',
        description : 'time epoch for time clients')
+option('clock-valid-range-usec-max', type : 'integer', value : '473364000000000', # 15 years
+       description : 'maximum value in microseconds for the difference between RTC and epoch, exceeding which is considered an RTC error')
 
 option('system-alloc-uid-min', type : 'integer', value : '-1',
        description : 'minimum system UID used when allocating')
@@ -353,6 +359,8 @@ option('microhttpd', type : 'combo', choices : ['auto', 'true', 'false'],
        description : 'libµhttpd support')
 option('libcryptsetup', type : 'combo', choices : ['auto', 'true', 'false'],
        description : 'libcryptsetup support')
+option('libcryptsetup-plugins', type : 'combo', choices : ['auto', 'true', 'false'],
+       description : 'libcryptsetup LUKS2 external token handlers support (plugins)')
 option('libcurl', type : 'combo', choices : ['auto', 'true', 'false'],
        description : 'libcurl support')
 option('idn', type : 'boolean',
@@ -444,6 +452,8 @@ option('ok-color', type : 'combo',
                   'highlight-cyan', 'highlight-white'],
        value : 'green',
        description: 'color of the "OK" status message')
+option('urlify', type : 'boolean', value : 'true',
+       description : 'enable pager Hyperlink ANSI sequence support')
 option('fexecve', type : 'boolean', value : 'false',
        description : 'use fexecve() to spawn children')
 
index b0e60f72176b38716565ae5e784a4da0517aba2c..ccfd79e8dabad0a8052ab02f095eee544b7acc4c 100644 (file)
@@ -12,7 +12,7 @@ if conf.get('ENABLE_NETWORKD') == 1
 
         if install_sysconfdir
                 meson.add_install_script('sh', '-c',
-                                         mkdir_p.format(join_paths(sysconfdir, 'systemd/network')))
+                                         mkdir_p.format(sysconfdir / 'systemd/network'))
         endif
 endif
 
index d26087445c9695ded99f3b620e7985a1a64f4099..8a1a08210cfe269be1bc54c0c06635e7c2295927 100644 (file)
@@ -22,6 +22,7 @@ enable systemd-resolved.service
 enable systemd-homed.service
 enable systemd-userdbd.socket
 enable systemd-pstore.service
+enable systemd-boot-update.service
 
 disable console-getty.service
 disable debug-shell.service
index c26b413d926d9ea4d5d06cceb213e00533f57553..0946bc5b54302d1be4e7d14b3d8c4c6c80e5a0c7 100644 (file)
@@ -6,7 +6,7 @@ if bashcompletiondir == ''
         if bash_completion.found()
                 bashcompletiondir = bash_completion.get_pkgconfig_variable('completionsdir')
         else
-                bashcompletiondir = join_paths(datadir, 'bash-completion/completions')
+                bashcompletiondir = datadir / 'bash-completion/completions'
         endif
 endif
 
index cd0ad8245f7579b4db928ac4bfdc0843af69c3f8..934834b94be8571cd4b473c1181b23b70df1e90e 100644 (file)
@@ -77,4 +77,5 @@ _arguments \
     '--version[Show package version]' \
     '--wait=[Wait until service stopped again]' \
     '--working-directory=[Run with the specified working directory]' \
-    '*::command:_command'
+    '(-):command: _command_names -e' \
+    '*::arguments:_normal'
index f5f9b0f993f044376f74627ecc5a4474bf1b3d57..ce3a304d45c23954c10ca9b903baa582401493d2 100644 (file)
@@ -2,7 +2,7 @@
 
 zshcompletiondir = get_option('zshcompletiondir')
 if zshcompletiondir == ''
-        zshcompletiondir = join_paths(datadir, 'zsh/site-functions')
+        zshcompletiondir = datadir / 'zsh/site-functions'
 endif
 
 custom_target(
index 905da4ad879161230e106b83e433f03620f04ad2..c4bfe7cb18effc8dcdc2b10b6bf79d5207b864f3 100644 (file)
@@ -53,7 +53,7 @@ static int parse_argv(int argc, char *argv[]) {
                         return -EINVAL;
 
                 default:
-                        assert_not_reached("Unhandled option");
+                        assert_not_reached();
                 }
 
         if (optind < argc)
index 8c61c3ca7fc2eb091bfd30e6215343bf3fa921b7..18ce491a848c5c1d01e1ab132d6a1654595c6655 100644 (file)
@@ -453,7 +453,7 @@ static int parse_argv(int argc, char *argv[]) {
                         return -EINVAL;
 
                 default:
-                        assert_not_reached("Unhandled option");
+                        assert_not_reached();
                 }
 
         if (optind == argc)
index f20606c17ca4fc01110ba9a14d4b3d463cd77b80..4d41834c3f85fc5e7739e2c7311f59817740bb3a 100644 (file)
@@ -583,11 +583,12 @@ static int assess_system_call_filter(
         assert(a->parameter < _SYSCALL_FILTER_SET_MAX);
         const SyscallFilterSet *f = syscall_filter_sets + a->parameter;
 
-        char *d = NULL;
+        _cleanup_free_ char *d = NULL;
         uint64_t b;
+        int r;
 
         if (!info->system_call_filter_allow_list && set_isempty(info->system_call_filter)) {
-                d = strdup("Service does not filter system calls");
+                r = free_and_strdup(&d, "Service does not filter system calls");
                 b = 10;
         } else {
                 bool bad;
@@ -599,34 +600,33 @@ static int assess_system_call_filter(
 
                 if (info->system_call_filter_allow_list) {
                         if (bad) {
-                                (void) asprintf(&d, "System call allow list defined for service, and %s is included "
-                                                "(e.g. %s is allowed)",
-                                                f->name, offender);
+                                r = asprintf(&d, "System call allow list defined for service, and %s is included "
+                                             "(e.g. %s is allowed)",
+                                             f->name, offender);
                                 b = 9;
                         } else {
-                                (void) asprintf(&d, "System call allow list defined for service, and %s is not included",
-                                                f->name);
+                                r = asprintf(&d, "System call allow list defined for service, and %s is not included",
+                                             f->name);
                                 b = 0;
                         }
                 } else {
                         if (bad) {
-                                (void) asprintf(&d, "System call deny list defined for service, and %s is not included "
-                                                "(e.g. %s is allowed)",
-                                                f->name, offender);
+                                r = asprintf(&d, "System call deny list defined for service, and %s is not included "
+                                             "(e.g. %s is allowed)",
+                                             f->name, offender);
                                 b = 10;
                         } else {
-                                (void) asprintf(&d, "System call deny list defined for service, and %s is included",
-                                                f->name);
+                                r = asprintf(&d, "System call deny list defined for service, and %s is included",
+                                             f->name);
                                 b = 0;
                         }
                 }
         }
-
-        if (!d)
+        if (r < 0)
                 return log_oom();
 
         *ret_badness = b;
-        *ret_description = d;
+        *ret_description = TAKE_PTR(d);
 
         return 0;
 }
index 62c0ccbdfe3a732287b5d65b1d75eb571dcf4a45..e7600934eaa6ba524574805087e053183ae16abb 100644 (file)
@@ -479,7 +479,6 @@ manager:
 }
 
 static int pretty_boot_time(sd_bus *bus, char **_buf) {
-        char ts[FORMAT_TIMESPAN_MAX];
         BootTimes *t;
         static char buf[4096];
         size_t size;
@@ -524,23 +523,23 @@ static int pretty_boot_time(sd_bus *bus, char **_buf) {
 
         size = strpcpyf(&ptr, size, "Startup finished in ");
         if (t->firmware_time > 0)
-                size = strpcpyf(&ptr, size, "%s (firmware) + ", format_timespan(ts, sizeof(ts), t->firmware_time - t->loader_time, USEC_PER_MSEC));
+                size = strpcpyf(&ptr, size, "%s (firmware) + ", FORMAT_TIMESPAN(t->firmware_time - t->loader_time, USEC_PER_MSEC));
         if (t->loader_time > 0)
-                size = strpcpyf(&ptr, size, "%s (loader) + ", format_timespan(ts, sizeof(ts), t->loader_time, USEC_PER_MSEC));
+                size = strpcpyf(&ptr, size, "%s (loader) + ", FORMAT_TIMESPAN(t->loader_time, USEC_PER_MSEC));
         if (t->kernel_done_time > 0)
-                size = strpcpyf(&ptr, size, "%s (kernel) + ", format_timespan(ts, sizeof(ts), t->kernel_done_time, USEC_PER_MSEC));
+                size = strpcpyf(&ptr, size, "%s (kernel) + ", FORMAT_TIMESPAN(t->kernel_done_time, USEC_PER_MSEC));
         if (t->initrd_time > 0)
-                size = strpcpyf(&ptr, size, "%s (initrd) + ", format_timespan(ts, sizeof(ts), t->userspace_time - t->initrd_time, USEC_PER_MSEC));
+                size = strpcpyf(&ptr, size, "%s (initrd) + ", FORMAT_TIMESPAN(t->userspace_time - t->initrd_time, USEC_PER_MSEC));
 
-        size = strpcpyf(&ptr, size, "%s (userspace) ", format_timespan(ts, sizeof(ts), t->finish_time - t->userspace_time, USEC_PER_MSEC));
+        size = strpcpyf(&ptr, size, "%s (userspace) ", FORMAT_TIMESPAN(t->finish_time - t->userspace_time, USEC_PER_MSEC));
         if (t->kernel_done_time > 0)
-                strpcpyf(&ptr, size, "= %s ", format_timespan(ts, sizeof(ts), t->firmware_time + t->finish_time, USEC_PER_MSEC));
+                strpcpyf(&ptr, size, "= %s ", FORMAT_TIMESPAN(t->firmware_time + t->finish_time, USEC_PER_MSEC));
 
         if (unit_id && timestamp_is_set(activated_time)) {
                 usec_t base = t->userspace_time > 0 ? t->userspace_time : t->reverse_offset;
 
                 size = strpcpyf(&ptr, size, "\n%s reached after %s in userspace", unit_id,
-                                format_timespan(ts, sizeof(ts), activated_time - base, USEC_PER_MSEC));
+                                FORMAT_TIMESPAN(activated_time - base, USEC_PER_MSEC));
         } else if (unit_id && activated_time == 0)
                 size = strpcpyf(&ptr, size, "\n%s was never reached", unit_id);
         else if (unit_id && activated_time == USEC_INFINITY)
@@ -591,7 +590,6 @@ static void svg_graph_box(double height, double begin, double end) {
 }
 
 static int plot_unit_times(UnitTimes *u, double width, int y) {
-        char ts[FORMAT_TIMESPAN_MAX];
         bool b;
 
         if (!u->name)
@@ -605,7 +603,7 @@ static int plot_unit_times(UnitTimes *u, double width, int y) {
         b = u->activating * SCALE_X < width / 2;
         if (u->time)
                 svg_text(b, u->activating, y, "%s (%s)",
-                         u->name, format_timespan(ts, sizeof(ts), u->time, USEC_PER_MSEC));
+                         u->name, FORMAT_TIMESPAN(u->time, USEC_PER_MSEC));
         else
                 svg_text(b, u->activating, y, "%s", u->name);
 
@@ -836,8 +834,6 @@ static int list_dependencies_print(
                 UnitTimes *times,
                 BootTimes *boot) {
 
-        char ts[FORMAT_TIMESPAN_MAX], ts2[FORMAT_TIMESPAN_MAX];
-
         for (unsigned i = level; i != 0; i--)
                 printf("%s", special_glyph(branches & (1 << (i-1)) ? SPECIAL_GLYPH_TREE_VERTICAL : SPECIAL_GLYPH_TREE_SPACE));
 
@@ -846,10 +842,10 @@ static int list_dependencies_print(
         if (times) {
                 if (times->time > 0)
                         printf("%s%s @%s +%s%s", ansi_highlight_red(), name,
-                               format_timespan(ts, sizeof(ts), times->activating - boot->userspace_time, USEC_PER_MSEC),
-                               format_timespan(ts2, sizeof(ts2), times->time, USEC_PER_MSEC), ansi_normal());
+                               FORMAT_TIMESPAN(times->activating - boot->userspace_time, USEC_PER_MSEC),
+                               FORMAT_TIMESPAN(times->time, USEC_PER_MSEC), ansi_normal());
                 else if (times->activated > boot->userspace_time)
-                        printf("%s @%s", name, format_timespan(ts, sizeof(ts), times->activated - boot->userspace_time, USEC_PER_MSEC));
+                        printf("%s @%s", name, FORMAT_TIMESPAN(times->activated - boot->userspace_time, USEC_PER_MSEC));
                 else
                         printf("%s", name);
         } else
@@ -964,7 +960,6 @@ static int list_dependencies_one(sd_bus *bus, const char *name, unsigned level,
 
 static int list_dependencies(sd_bus *bus, const char *name) {
         _cleanup_strv_free_ char **units = NULL;
-        char ts[FORMAT_TIMESPAN_MAX];
         UnitTimes *times;
         int r;
         const char *id;
@@ -1004,9 +999,10 @@ static int list_dependencies(sd_bus *bus, const char *name) {
         if (times) {
                 if (times->time)
                         printf("%s%s +%s%s\n", ansi_highlight_red(), id,
-                               format_timespan(ts, sizeof(ts), times->time, USEC_PER_MSEC), ansi_normal());
+                               FORMAT_TIMESPAN(times->time, USEC_PER_MSEC), ansi_normal());
                 else if (times->activated > boot->userspace_time)
-                        printf("%s @%s\n", id, format_timespan(ts, sizeof(ts), times->activated - boot->userspace_time, USEC_PER_MSEC));
+                        printf("%s @%s\n", id,
+                               FORMAT_TIMESPAN(times->activated - boot->userspace_time, USEC_PER_MSEC));
                 else
                         printf("%s\n", id);
         }
@@ -2370,7 +2366,7 @@ static int parse_argv(int argc, char *argv[]) {
                         return -EINVAL;
 
                 default:
-                        assert_not_reached("Unhandled option code.");
+                        assert_not_reached();
                 }
 
         if (arg_scope == UNIT_FILE_GLOBAL &&
index 45305dec1f0dc39f278a35ac55b200f66c767402..a100679af211f58e37488d6717ba038fc1badc16 100644 (file)
@@ -188,7 +188,7 @@ static int parse_argv(int argc, char *argv[]) {
                         return -EINVAL;
 
                 default:
-                        assert_not_reached("Unhandled option");
+                        assert_not_reached();
                 }
 
         if (isempty(emoji) || streq(emoji, "auto"))
index 7c0970a60c24502a587784fd52ce05ce609934b7..6fcf58466752385bd3eeb77eb09658951cae6ec6 100644 (file)
@@ -495,7 +495,7 @@ static int run(int argc, char *argv[]) {
                         return log_device_error_errno(device, r, "Failed to write %s: %m", saved);
 
         } else
-                assert_not_reached("Unknown verb.");
+                assert_not_reached();
 
         return 0;
 }
index 3c33308f481c9748687db42dcfb7e0eeea1bad54..0af425e4914ffc31ef1e3cf3dc7816ec969990bc 100644 (file)
@@ -51,9 +51,11 @@ static inline void *mfree(void *memory) {
 
 #define free_and_replace(a, b)                  \
         ({                                      \
-                free(a);                        \
-                (a) = (b);                      \
-                (b) = NULL;                     \
+                typeof(a)* _a = &(a);           \
+                typeof(b)* _b = &(b);           \
+                free(*_a);                      \
+                (*_a) = (*_b);                  \
+                (*_b) = NULL;                   \
                 0;                              \
         })
 
index 409632c3f49d6f0e11d678dc4afc95fc6b39f9aa..e5dafb98141e59aa0632ff94381095def1f5d251 100644 (file)
@@ -136,7 +136,7 @@ int uname_architecture(void) {
                 if (streq(arch_map[i].machine, u.machine))
                         return cached = arch_map[i].arch;
 
-        assert_not_reached("Couldn't identify architecture. You need to patch systemd.");
+        assert_not_reached();
         return _ARCHITECTURE_INVALID;
 }
 
index 032ae6f9a1ce209583517e84bfbda9464c0f21ca..3e5c5e68dd0b5906edb8577cfc60c92e4a73a34a 100644 (file)
@@ -120,13 +120,10 @@ int efi_get_variable(
                 n = st.st_size - 4;
 
         if (DEBUG_LOGGING) {
-                char ts[FORMAT_TIMESPAN_MAX];
-                usec_t end;
-
-                end = now(CLOCK_MONOTONIC);
+                usec_t end = now(CLOCK_MONOTONIC);
                 if (end > begin + EFI_RETRY_DELAY)
                         log_debug("Detected slow EFI variable read access on %s: %s",
-                                  variable, format_timespan(ts, sizeof(ts), end - begin, 1));
+                                  variable, FORMAT_TIMESPAN(end - begin, 1));
         }
 
         /* Note that efivarfs interestingly doesn't require ftruncate() to update an existing EFI variable
@@ -382,7 +379,7 @@ int systemd_efi_options_efivarfs_if_newer(char **line) {
                 return log_debug_errno(errno, "Failed to stat EFI variable SystemdOptions: %m");
 
         if (stat(EFIVAR_CACHE_PATH(EFI_SYSTEMD_VARIABLE(SystemdOptions)), &b) < 0) {
-                if (errno != -ENOENT)
+                if (errno != ENOENT)
                         log_debug_errno(errno, "Failed to stat "EFIVAR_CACHE_PATH(EFI_SYSTEMD_VARIABLE(SystemdOptions))": %m");
         } else if (compare_stat_mtime(&a, &b) > 0)
                 log_debug("Variable SystemdOptions in evifarfs is newer than in cache.");
index 2a3a0e31a1ec24291a85bfd8ada22b28fa51af89..4bb98f9342bc0d0b5f5ea9b6fcb229b3e15b96ee 100644 (file)
@@ -8,6 +8,7 @@
 #include "escape.h"
 #include "hexdecoct.h"
 #include "macro.h"
+#include "strv.h"
 #include "utf8.h"
 
 int cescape_char(char c, char *buf) {
@@ -288,10 +289,12 @@ int cunescape_one(const char *p, size_t length, char32_t *ret, bool *eight_bit,
         return r;
 }
 
-int cunescape_length_with_prefix(const char *s, size_t length, const char *prefix, UnescapeFlags flags, char **ret) {
-        char *r, *t;
+ssize_t cunescape_length_with_prefix(const char *s, size_t length, const char *prefix, UnescapeFlags flags, char **ret) {
+        _cleanup_free_ char *ans = NULL;
+        char *t;
         const char *f;
         size_t pl;
+        int r;
 
         assert(s);
         assert(ret);
@@ -300,18 +303,17 @@ int cunescape_length_with_prefix(const char *s, size_t length, const char *prefi
 
         pl = strlen_ptr(prefix);
 
-        r = new(char, pl+length+1);
-        if (!r)
+        ans = new(char, pl+length+1);
+        if (!ans)
                 return -ENOMEM;
 
         if (prefix)
-                memcpy(r, prefix, pl);
+                memcpy(ans, prefix, pl);
 
-        for (f = s, t = r + pl; f < s + length; f++) {
+        for (f = s, t = ans + pl; f < s + length; f++) {
                 size_t remaining;
                 bool eight_bit = false;
                 char32_t u;
-                int k;
 
                 remaining = s + length - f;
                 assert(remaining > 0);
@@ -329,23 +331,21 @@ int cunescape_length_with_prefix(const char *s, size_t length, const char *prefi
                                 continue;
                         }
 
-                        free(r);
                         return -EINVAL;
                 }
 
-                k = cunescape_one(f + 1, remaining - 1, &u, &eight_bit, flags & UNESCAPE_ACCEPT_NUL);
-                if (k < 0) {
+                r = cunescape_one(f + 1, remaining - 1, &u, &eight_bit, flags & UNESCAPE_ACCEPT_NUL);
+                if (r < 0) {
                         if (flags & UNESCAPE_RELAX) {
                                 /* Invalid escape code, let's take it literal then */
                                 *(t++) = '\\';
                                 continue;
                         }
 
-                        free(r);
-                        return k;
+                        return r;
                 }
 
-                f += k;
+                f += r;
                 if (eight_bit)
                         /* One byte? Set directly as specified */
                         *(t++) = u;
@@ -356,8 +356,9 @@ int cunescape_length_with_prefix(const char *s, size_t length, const char *prefi
 
         *t = 0;
 
-        *ret = r;
-        return t - r;
+        assert(t >= ans); /* Let static analyzers know that the answer is non-negative. */
+        *ret = TAKE_PTR(ans);
+        return t - *ret;
 }
 
 char* xescape_full(const char *s, const char *bad, size_t console_width, XEscapeFlags flags) {
@@ -542,3 +543,23 @@ char* shell_maybe_quote(const char *s, ShellEscapeFlags flags) {
 
         return str_realloc(buf);
 }
+
+char* quote_command_line(char **argv) {
+        _cleanup_free_ char *result = NULL;
+
+        assert(argv);
+
+        char **a;
+        STRV_FOREACH(a, argv) {
+                _cleanup_free_ char *t = NULL;
+
+                t = shell_maybe_quote(*a, SHELL_ESCAPE_EMPTY);
+                if (!t)
+                        return NULL;
+
+                if (!strextend_with_separator(&result, " ", t))
+                        return NULL;
+        }
+
+        return TAKE_PTR(result);
+}
index 907b572bd4ad8d7a21b2cf8a1545b4f13bf7465e..d490510deb1e8a1b3c3bae240f051793e303cc2f 100644 (file)
@@ -45,14 +45,15 @@ char* cescape(const char *s);
 char* cescape_length(const char *s, size_t n);
 int cescape_char(char c, char *buf);
 
-int cunescape_length_with_prefix(const char *s, size_t length, const char *prefix, UnescapeFlags flags, char **ret);
-static inline int cunescape_length(const char *s, size_t length, UnescapeFlags flags, char **ret) {
+int cunescape_one(const char *p, size_t length, char32_t *ret, bool *eight_bit, bool accept_nul);
+
+ssize_t cunescape_length_with_prefix(const char *s, size_t length, const char *prefix, UnescapeFlags flags, char **ret);
+static inline ssize_t cunescape_length(const char *s, size_t length, UnescapeFlags flags, char **ret) {
         return cunescape_length_with_prefix(s, length, NULL, flags, ret);
 }
-static inline int cunescape(const char *s, UnescapeFlags flags, char **ret) {
+static inline ssize_t cunescape(const char *s, UnescapeFlags flags, char **ret) {
         return cunescape_length(s, strlen(s), flags, ret);
 }
-int cunescape_one(const char *p, size_t length, char32_t *ret, bool *eight_bit, bool accept_nul);
 
 typedef enum XEscapeFlags {
         XESCAPE_8_BIT          = 1 << 0,
@@ -68,3 +69,4 @@ char* escape_non_printable_full(const char *str, size_t console_width, XEscapeFl
 
 char* shell_escape(const char *s, const char *bad);
 char* shell_maybe_quote(const char *s, ShellEscapeFlags flags);
+char* quote_command_line(char **argv);
index 63447910c09afd9fcb437f903eccb75c79c25e7e..794fc55bb837b5812b750ae5e10a154389503944 100644 (file)
@@ -23,7 +23,9 @@ struct hw_addr_data {
 #define HW_ADDR_TO_STRING_MAX (3*HW_ADDR_MAX_SIZE)
 char* hw_addr_to_string(const struct hw_addr_data *addr, char buffer[HW_ADDR_TO_STRING_MAX]);
 
-/* Use only as function argument, never stand-alone! */
+/* Note: the lifetime of the compound literal is the immediately surrounding block,
+ * see C11 §6.5.2.5, and
+ * https://stackoverflow.com/questions/34880638/compound-literal-lifetime-and-if-blocks */
 #define HW_ADDR_TO_STR(hw_addr) hw_addr_to_string((hw_addr), (char[HW_ADDR_TO_STRING_MAX]){})
 
 #define HW_ADDR_NULL ((const struct hw_addr_data){})
index 008f474344df51189021b86429d10e57553fb35c..6b6457dbc22a6baffb77b27c71ccef5b37e3cfe0 100644 (file)
@@ -208,10 +208,9 @@ static int get_max_fd(void) {
         return (int) (m - 1);
 }
 
-int close_all_fds(const int except[], size_t n_except) {
+int close_all_fds_full(int except[], size_t n_except, bool allow_alloc) {
         static bool have_close_range = true; /* Assume we live in the future */
         _cleanup_closedir_ DIR *d = NULL;
-        struct dirent *de;
         int r = 0;
 
         assert(n_except == 0 || except);
@@ -227,129 +226,104 @@ int close_all_fds(const int except[], size_t n_except) {
                         /* Close everything. Yay! */
 
                         if (close_range(3, -1, 0) >= 0)
-                                return 1;
+                                return 0;
 
-                        if (!ERRNO_IS_NOT_SUPPORTED(errno) && !ERRNO_IS_PRIVILEGE(errno))
+                        if (ERRNO_IS_NOT_SUPPORTED(errno) || ERRNO_IS_PRIVILEGE(errno))
+                                have_close_range = false;
+                        else
                                 return -errno;
 
-                        have_close_range = false;
                 } else {
-                        _cleanup_free_ int *sorted_malloc = NULL;
-                        size_t n_sorted;
-                        int *sorted;
-
-                        assert(n_except < SIZE_MAX);
-                        n_sorted = n_except + 1;
-
-                        if (n_sorted > 64) /* Use heap for large numbers of fds, stack otherwise */
-                                sorted = sorted_malloc = new(int, n_sorted);
-                        else
-                                sorted = newa(int, n_sorted);
-
-                        if (sorted) {
-                                int c = 0;
-
-                                memcpy(sorted, except, n_except * sizeof(int));
-
-                                /* Let's add fd 2 to the list of fds, to simplify the loop below, as this
-                                 * allows us to cover the head of the array the same way as the body */
-                                sorted[n_sorted-1] = 2;
+                        typesafe_qsort(except, n_except, cmp_int);
 
-                                typesafe_qsort(sorted, n_sorted, cmp_int);
+                        for (size_t i = 0; i < n_except; i++) {
+                                int start = i == 0 ? 2 : MAX(except[i-1], 2); /* The first three fds shall always remain open */
+                                int end = MAX(except[i], 2);
 
-                                for (size_t i = 0; i < n_sorted-1; i++) {
-                                        int start, end;
+                                assert(end >= start);
 
-                                        start = MAX(sorted[i], 2); /* The first three fds shall always remain open */
-                                        end = MAX(sorted[i+1], 2);
-
-                                        assert(end >= start);
-
-                                        if (end - start <= 1)
-                                                continue;
-
-                                        /* Close everything between the start and end fds (both of which shall stay open) */
-                                        if (close_range(start + 1, end - 1, 0) < 0) {
-                                                if (!ERRNO_IS_NOT_SUPPORTED(errno) && !ERRNO_IS_PRIVILEGE(errno))
-                                                        return -errno;
+                                if (end - start <= 1)
+                                        continue;
 
+                                /* Close everything between the start and end fds (both of which shall stay open) */
+                                if (close_range(start + 1, end - 1, 0) < 0) {
+                                        if (ERRNO_IS_NOT_SUPPORTED(errno) || ERRNO_IS_PRIVILEGE(errno))
                                                 have_close_range = false;
-                                                break;
-                                        }
-
-                                        c += end - start - 1;
+                                        else
+                                                return -errno;
+                                        goto opendir_fallback;
                                 }
+                        }
 
-                                if (have_close_range) {
-                                        /* The loop succeeded. Let's now close everything beyond the end */
+                        /* The loop succeeded. Let's now close everything beyond the end */
 
-                                        if (sorted[n_sorted-1] >= INT_MAX) /* Dont let the addition below overflow */
-                                                return c;
+                        if (except[n_except-1] >= INT_MAX) /* Don't let the addition below overflow */
+                                return 0;
 
-                                        if (close_range(sorted[n_sorted-1] + 1, -1, 0) >= 0)
-                                                return c + 1;
+                        int start = MAX(except[n_except-1], 2);
 
-                                        if (!ERRNO_IS_NOT_SUPPORTED(errno) && !ERRNO_IS_PRIVILEGE(errno))
-                                                return -errno;
+                        if (close_range(start + 1, -1, 0) >= 0)
+                                return 0;
 
-                                        have_close_range = false;
-                                }
-                        }
+                        if (ERRNO_IS_NOT_SUPPORTED(errno) || ERRNO_IS_PRIVILEGE(errno))
+                                have_close_range = false;
+                        else
+                                return -errno;
                 }
-
-                /* Fallback on OOM or if close_range() is not supported */
         }
 
-        d = opendir("/proc/self/fd");
-        if (!d) {
-                int fd, max_fd;
+        /* Fallback for when close_range() is not supported */
+ opendir_fallback:
+        d = allow_alloc ? opendir("/proc/self/fd") : NULL;
+        if (d) {
+                struct dirent *de;
 
-                /* When /proc isn't available (for example in chroots) the fallback is brute forcing through
-                 * the fd table */
+                FOREACH_DIRENT(de, d, return -errno) {
+                        int fd = -1, q;
 
-                max_fd = get_max_fd();
-                if (max_fd < 0)
-                        return max_fd;
+                        if (safe_atoi(de->d_name, &fd) < 0)
+                                /* Let's better ignore this, just in case */
+                                continue;
 
-                /* Refuse to do the loop over more too many elements. It's better to fail immediately than to
-                 * spin the CPU for a long time. */
-                if (max_fd > MAX_FD_LOOP_LIMIT)
-                        return log_debug_errno(SYNTHETIC_ERRNO(EPERM),
-                                               "/proc/self/fd is inaccessible. Refusing to loop over %d potential fds.",
-                                               max_fd);
+                        if (fd < 3)
+                                continue;
 
-                for (fd = 3; fd >= 0; fd = fd < max_fd ? fd + 1 : -1) {
-                        int q;
+                        if (fd == dirfd(d))
+                                continue;
 
                         if (fd_in_set(fd, except, n_except))
                                 continue;
 
                         q = close_nointr(fd);
-                        if (q < 0 && q != -EBADF && r >= 0)
+                        if (q < 0 && q != -EBADF && r >= 0) /* Valgrind has its own FD and doesn't want to have it closed */
                                 r = q;
                 }
 
                 return r;
         }
 
-        FOREACH_DIRENT(de, d, return -errno) {
-                int fd = -1, q;
+        /* Fallback for when /proc isn't available (for example in chroots) or when we cannot allocate by
+         * brute-forcing through the file descriptor table. */
 
-                if (safe_atoi(de->d_name, &fd) < 0)
-                        /* Let's better ignore this, just in case */
-                        continue;
+        int max_fd = get_max_fd();
+        if (max_fd < 0)
+                return max_fd;
 
-                if (fd < 3)
-                        continue;
+        /* Refuse to do the loop over more too many elements. It's better to fail immediately than to
+         * spin the CPU for a long time. */
+        if (max_fd > MAX_FD_LOOP_LIMIT)
+                return log_debug_errno(SYNTHETIC_ERRNO(EPERM),
+                                       "/proc/self/fd is inaccessible. Refusing to loop over %d potential fds.",
+                                       max_fd);
 
-                if (fd == dirfd(d))
-                        continue;
+        for (int fd = 3; fd >= 0; fd = fd < max_fd ? fd + 1 : -1) {
+                int q;
 
                 if (fd_in_set(fd, except, n_except))
                         continue;
 
                 q = close_nointr(fd);
-                if (q < 0 && q != -EBADF && r >= 0) /* Valgrind has its own FD and doesn't want to have it closed */
+                if (q < 0 && q != -EBADF && r >= 0)
                         r = q;
         }
 
index 9529a4723d39fa2060acd233de735eee348babc8..61b6684cb3c156a8d9040bf6acce590d406d1c44 100644 (file)
@@ -56,7 +56,10 @@ DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(DIR*, closedir, NULL);
 int fd_nonblock(int fd, bool nonblock);
 int fd_cloexec(int fd, bool cloexec);
 
-int close_all_fds(const int except[], size_t n_except);
+int close_all_fds_full(int except[], size_t n_except, bool allow_alloc);
+static inline int close_all_fds(int except[], size_t n_except) {
+        return close_all_fds_full(except, n_except, true);
+}
 
 int same_fd(int a, int b);
 
index af797cfafdbf5372a1a8f946c8efdf09d2fb0f77..4295b84a85c59494a091795dc65035471a19164e 100644 (file)
@@ -2,11 +2,11 @@
 #pragma once
 
 #include <dirent.h>
+#include <fcntl.h>
 #include <stdbool.h>
 #include <stddef.h>
 #include <stdio.h>
 #include <sys/stat.h>
-#include <sys/fcntl.h>
 #include <sys/types.h>
 
 #include "macro.h"
index b7e18768e392e034d0a56b056192dbdc040cf800..579f2318975781d46a412c5f238edaf0b1088d49 100644 (file)
@@ -74,16 +74,17 @@ typedef enum {
 
 #define FORMAT_BYTES_MAX 16U
 
-char *format_bytes_full(char *buf, size_t l, uint64_t t, FormatBytesFlag flag);
+char *format_bytes_full(char *buf, size_t l, uint64_t t, FormatBytesFlag flag) _warn_unused_result_;
 
+_warn_unused_result_
 static inline char *format_bytes(char *buf, size_t l, uint64_t t) {
         return format_bytes_full(buf, l, t, FORMAT_BYTES_USE_IEC | FORMAT_BYTES_BELOW_POINT | FORMAT_BYTES_TRAILING_B);
 }
 
-static inline char *format_bytes_cgroup_protection(char *buf, size_t l, uint64_t t) {
-        if (t == CGROUP_LIMIT_MAX) {
-                (void) snprintf(buf, l, "%s", "infinity");
-                return buf;
-        }
-        return format_bytes(buf, l, t);
-}
+/* Note: the lifetime of the compound literal is the immediately surrounding block,
+ * see C11 §6.5.2.5, and
+ * https://stackoverflow.com/questions/34880638/compound-literal-lifetime-and-if-blocks */
+#define FORMAT_BYTES(t) format_bytes((char[FORMAT_BYTES_MAX]){}, FORMAT_BYTES_MAX, t)
+#define FORMAT_BYTES_FULL(t, flag) format_bytes_full((char[FORMAT_BYTES_MAX]){}, FORMAT_BYTES_MAX, t, flag)
+
+#define FORMAT_BYTES_CGROUP_PROTECTION(t) (t == CGROUP_LIMIT_MAX ? "infinity" : FORMAT_BYTES(t))
index 0decbb04e10fdba6e458b033c5f34044f8516fdb..b51d70bc87928d0a708ba7b079110dde7f6d8be0 100644 (file)
@@ -401,7 +401,7 @@ static struct hashmap_base_entry* bucket_at_virtual(HashmapBase *h, struct swap_
         if (idx < _IDX_SWAP_END)
                 return &bucket_at_swap(swap, idx)->p.b;
 
-        assert_not_reached("Invalid index");
+        assert_not_reached();
 }
 
 static dib_raw_t* dib_raw_ptr(HashmapBase *h) {
@@ -513,7 +513,7 @@ static void* entry_value(HashmapBase *h, struct hashmap_base_entry *e) {
                 return (void*) e->key;
 
         default:
-                assert_not_reached("Unknown hashmap type");
+                assert_not_reached();
         }
 }
 
@@ -1747,7 +1747,7 @@ HashmapBase* _hashmap_copy(HashmapBase *h  HASHMAP_DEBUG_PARAMS) {
                 r = set_merge((Set*)copy, (Set*)h);
                 break;
         default:
-                assert_not_reached("Unknown hashmap type");
+                assert_not_reached();
         }
 
         if (r < 0)
index 172ae8a9218b9644bc68ca8788cd15ccc2b63737..8c83a0e71a6befe1b6549d5ea8c1c921b40449c0 100644 (file)
@@ -645,6 +645,7 @@ ssize_t base64mem_full(
 
         *z = 0;
         *out = r;
+        assert(z >= r); /* Let static analyzers know that the answer is non-negative. */
         return z - r;
 }
 
index 9cc92a1c767bf83746bb2129ce75860a0857ac0d..2187bd0cbacf2522ea78cfa28ff144f5a5b687ef 100644 (file)
@@ -794,7 +794,7 @@ int in_addr_prefix_from_string_auto_internal(
                                 k = 0;
                         break;
                 default:
-                        assert_not_reached("Invalid prefixlen mode");
+                        assert_not_reached();
                 }
 
         if (ret_family)
index fd6b01cfaade6f0441b61222964322e667ede998..007e3a091ecd38df4375814a75a0c918391b3f4e 100644 (file)
@@ -375,6 +375,9 @@ const char *special_glyph(SpecialGlyph code) {
                         [SPECIAL_GLYPH_DEPRESSED_SMILEY]        = ":-[",
                         [SPECIAL_GLYPH_LOCK_AND_KEY]            = "o-,",
                         [SPECIAL_GLYPH_TOUCH]                   = "O=",    /* Yeah, not very convincing, can you do it better? */
+                        [SPECIAL_GLYPH_RECYCLING]               = "~",
+                        [SPECIAL_GLYPH_DOWNLOAD]                = "\\",
+                        [SPECIAL_GLYPH_SPARKLES]                = "*",
                 },
 
                 /* UTF-8 */
@@ -421,7 +424,12 @@ const char *special_glyph(SpecialGlyph code) {
                         [SPECIAL_GLYPH_LOCK_AND_KEY]            = "\360\237\224\220",         /* 🔐 (actually called: CLOSED LOCK WITH KEY) */
 
                         /* This emoji is a single character cell glyph in Unicode, and two in ASCII */
-                        [SPECIAL_GLYPH_TOUCH]                   = "\360\237\221\206",         /* 👆 (actually called: BACKHAND INDEX POINTING UP */
+                        [SPECIAL_GLYPH_TOUCH]                   = "\360\237\221\206",         /* 👆 (actually called: BACKHAND INDEX POINTING UP) */
+
+                        /* These three emojis are single character cell glyphs in Unicode and also in ASCII. */
+                        [SPECIAL_GLYPH_RECYCLING]               = "\u267B\uFE0F ",            /* ♻️  (actually called: UNIVERSAL RECYCLNG SYMBOL) */
+                        [SPECIAL_GLYPH_DOWNLOAD]                = "\u2935\uFE0F ",            /* ⤵️  (actually called: RIGHT ARROW CURVING DOWN) */
+                        [SPECIAL_GLYPH_SPARKLES]                = "\u2728",                   /* ✨ */
                 },
         };
 
index df259d1bbd9f169907e45382d0800dca67a3d6eb..3430eb6ee1ff98e62b64d31222abb2993d135d50 100644 (file)
@@ -69,6 +69,9 @@ typedef enum SpecialGlyph {
         SPECIAL_GLYPH_DEPRESSED_SMILEY,
         SPECIAL_GLYPH_LOCK_AND_KEY,
         SPECIAL_GLYPH_TOUCH,
+        SPECIAL_GLYPH_RECYCLING,
+        SPECIAL_GLYPH_DOWNLOAD,
+        SPECIAL_GLYPH_SPARKLES,
         _SPECIAL_GLYPH_MAX,
         _SPECIAL_GLYPH_INVALID = -EINVAL,
 } SpecialGlyph;
@@ -95,3 +98,7 @@ static inline void locale_variables_freep(char*(*l)[_VARIABLE_LC_MAX]) {
 static inline const char *special_glyph_check_mark(bool b) {
         return b ? special_glyph(SPECIAL_GLYPH_CHECK_MARK) : special_glyph(SPECIAL_GLYPH_CROSS_MARK);
 }
+
+static inline const char *special_glyph_check_mark_space(bool b) {
+        return b ? special_glyph(SPECIAL_GLYPH_CHECK_MARK) : " ";
+}
index fb183ea9e752b62ec81aa66acffd1714e1101a3c..7602536691a0d7fd6561521c5669d53191f01edd 100644 (file)
@@ -863,12 +863,11 @@ _noreturn_ void log_assert_failed(
 }
 
 _noreturn_ void log_assert_failed_unreachable(
-                const char *text,
                 const char *file,
                 int line,
                 const char *func) {
-        log_assert(LOG_CRIT, text, file, line, func,
-                   "Code should not be reached '%s' at %s:%u, function %s(). Aborting.");
+        log_assert(LOG_CRIT, "Code should not be reached", file, line, func,
+                   "%s at %s:%u, function %s(). Aborting. 💥");
         abort();
 }
 
index 738c181070337cf20b3eff5d20cf8879b989afe9..9a17cd6c3d77249f7b29161417bd190e46bc1e40 100644 (file)
@@ -174,7 +174,6 @@ _noreturn_ void log_assert_failed(
                 const char *func);
 
 _noreturn_ void log_assert_failed_unreachable(
-                const char *text,
                 const char *file,
                 int line,
                 const char *func);
index 072fed4378931256fc9e3bc83cd2797652b0bc39..92498b0f20e189faec1acbb5ac683e8900372d83 100644 (file)
@@ -30,6 +30,7 @@
 #define _weakref_(x) __attribute__((__weakref__(#x)))
 #define _alignas_(x) __attribute__((__aligned__(__alignof(x))))
 #define _alignptr_ __attribute__((__aligned__(sizeof(void*))))
+#define _warn_unused_result_ __attribute__((__warn_unused_result__))
 #if __GNUC__ >= 7
 #define _fallthrough_ __attribute__((__fallthrough__))
 #else
@@ -213,7 +214,7 @@ static inline size_t GREEDY_ALLOC_ROUND_UP(size_t l) {
  *          Contrary to strlen(), this is a constant expression.
  * @x: a string literal.
  */
-#define STRLEN(x) (sizeof(""x"") - 1)
+#define STRLEN(x) (sizeof(""x"") - 1U)
 
 /*
  * container_of - cast a member of a structure out to the containing structure
@@ -281,8 +282,8 @@ static inline int __coverity_check_and_return__(int condition) {
 #define assert(expr) assert_message_se(expr, #expr)
 #endif
 
-#define assert_not_reached(t)                                           \
-        log_assert_failed_unreachable(t, PROJECT_FILE, __LINE__, __PRETTY_FUNCTION__)
+#define assert_not_reached(                                           \
+        log_assert_failed_unreachable(PROJECT_FILE, __LINE__, __PRETTY_FUNCTION__)
 
 #define assert_return(expr, r)                                          \
         do {                                                            \
@@ -341,15 +342,15 @@ static inline int __coverity_check_and_return__(int condition) {
  * negative '-' prefix (hence works correctly on signed
  * types). Includes space for the trailing NUL. */
 #define DECIMAL_STR_MAX(type)                                           \
-        (2+(sizeof(type) <= 1 ? 3 :                                     \
-            sizeof(type) <= 2 ? 5 :                                     \
-            sizeof(type) <= 4 ? 10 :                                    \
-            sizeof(type) <= 8 ? 20 : sizeof(int[-2*(sizeof(type) > 8)])))
+        (2U+(sizeof(type) <= 1 ? 3U :                                   \
+             sizeof(type) <= 2 ? 5U :                                   \
+             sizeof(type) <= 4 ? 10U :                                  \
+             sizeof(type) <= 8 ? 20U : sizeof(int[-2*(sizeof(type) > 8)])))
 
 #define DECIMAL_STR_WIDTH(x)                            \
         ({                                              \
                 typeof(x) _x_ = (x);                    \
-                unsigned ans = 1;                       \
+                size_t ans = 1;                         \
                 while ((_x_ /= 10) != 0)                \
                         ans++;                          \
                 ans;                                    \
index b79c885dfd21292bf10115f413f8ae93aa0ad7f6..70062eba2aa8a59bb5872f73fe0933ce246c4eb5 100644 (file)
@@ -2,7 +2,6 @@
 
 #include <errno.h>
 #include <inttypes.h>
-#include <linux/oom.h>
 #include <net/if.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -731,7 +730,7 @@ int parse_oom_score_adjust(const char *s, int *ret) {
         if (r < 0)
                 return r;
 
-        if (v < OOM_SCORE_ADJ_MIN || v > OOM_SCORE_ADJ_MAX)
+        if (!oom_score_adjust_is_valid(v))
                 return -ERANGE;
 
         *ret = v;
index 05eb17d66ccbb5f83056a5daa161c7776b31858f..987834b0d55ac1929d8b1b4a18ac9fb84d94cca7 100644 (file)
@@ -347,7 +347,7 @@ static int acquire_config_dirs(UnitFileScope scope, char **persistent, char **ru
                 return 0;
 
         default:
-                assert_not_reached("Hmm, unexpected scope value.");
+                assert_not_reached();
         }
 
         if (!a || !b)
@@ -405,7 +405,7 @@ static int acquire_control_dirs(UnitFileScope scope, char **persistent, char **r
                 return -EOPNOTSUPP;
 
         default:
-                assert_not_reached("Hmm, unexpected scope value.");
+                assert_not_reached();
         }
 
         *persistent = TAKE_PTR(a);
@@ -657,7 +657,7 @@ int lookup_paths_init(
                         break;
 
                 default:
-                        assert_not_reached("Hmm, unexpected scope?");
+                        assert_not_reached();
                 }
 
                 if (!add)
@@ -807,7 +807,7 @@ char **generator_binary_paths(UnitFileScope scope) {
                         break;
 
                 default:
-                        assert_not_reached("Hmm, unexpected scope.");
+                        assert_not_reached();
                 }
 
                 if (!add)
index 14259ea8dfe4a99371afe1537c0cd8e4eaf677cb..ecb14306f8b1ca64a1003115c6b4dc4cc598f3fd 100644 (file)
@@ -1037,30 +1037,6 @@ bool is_main_thread(void) {
         return cached > 0;
 }
 
-_noreturn_ void freeze(void) {
-
-        log_close();
-
-        /* Make sure nobody waits for us on a socket anymore */
-        (void) close_all_fds(NULL, 0);
-
-        sync();
-
-        /* Let's not freeze right away, but keep reaping zombies. */
-        for (;;) {
-                int r;
-                siginfo_t si = {};
-
-                r = waitid(P_ALL, 0, &si, WEXITED);
-                if (r < 0 && errno != EINTR)
-                        break;
-        }
-
-        /* waitid() failed with an unexpected error, things are really borked. Freeze now! */
-        for (;;)
-                pause();
-}
-
 bool oom_score_adjust_is_valid(int oa) {
         return oa >= OOM_SCORE_ADJ_MIN && oa <= OOM_SCORE_ADJ_MAX;
 }
@@ -1271,7 +1247,7 @@ static void restore_sigsetp(sigset_t **ssp) {
 
 int safe_fork_full(
                 const char *name,
-                const int except_fds[],
+                int except_fds[],
                 size_t n_except_fds,
                 ForkFlags flags,
                 pid_t *ret_pid) {
@@ -1466,7 +1442,7 @@ int safe_fork_full(
 int namespace_fork(
                 const char *outer_name,
                 const char *inner_name,
-                const int except_fds[],
+                int except_fds[],
                 size_t n_except_fds,
                 ForkFlags flags,
                 int pidns_fd,
@@ -1482,7 +1458,8 @@ int namespace_fork(
          * process. This ensures that we are fully a member of the destination namespace, with pidns an all, so that
          * /proc/self/fd works correctly. */
 
-        r = safe_fork_full(outer_name, except_fds, n_except_fds, (flags|FORK_DEATHSIG) & ~(FORK_REOPEN_LOG|FORK_NEW_MOUNTNS|FORK_MOUNTNS_SLAVE), ret_pid);
+        r = safe_fork_full(outer_name, except_fds, n_except_fds,
+                           (flags|FORK_DEATHSIG) & ~(FORK_REOPEN_LOG|FORK_NEW_MOUNTNS|FORK_MOUNTNS_SLAVE), ret_pid);
         if (r < 0)
                 return r;
         if (r == 0) {
@@ -1517,86 +1494,10 @@ int namespace_fork(
         return 1;
 }
 
-int fork_agent(const char *name, const int except[], size_t n_except, pid_t *ret_pid, const char *path, ...) {
-        bool stdout_is_tty, stderr_is_tty;
-        size_t n, i;
-        va_list ap;
-        char **l;
-        int r;
-
-        assert(path);
-
-        /* Spawns a temporary TTY agent, making sure it goes away when we go away */
-
-        r = safe_fork_full(name,
-                           except,
-                           n_except,
-                           FORK_RESET_SIGNALS|FORK_DEATHSIG|FORK_CLOSE_ALL_FDS|FORK_REOPEN_LOG,
-                           ret_pid);
-        if (r < 0)
-                return r;
-        if (r > 0)
-                return 0;
-
-        /* In the child: */
-
-        stdout_is_tty = isatty(STDOUT_FILENO);
-        stderr_is_tty = isatty(STDERR_FILENO);
-
-        if (!stdout_is_tty || !stderr_is_tty) {
-                int fd;
-
-                /* Detach from stdout/stderr. and reopen
-                 * /dev/tty for them. This is important to
-                 * ensure that when systemctl is started via
-                 * popen() or a similar call that expects to
-                 * read EOF we actually do generate EOF and
-                 * not delay this indefinitely by because we
-                 * keep an unused copy of stdin around. */
-                fd = open("/dev/tty", O_WRONLY);
-                if (fd < 0) {
-                        log_error_errno(errno, "Failed to open /dev/tty: %m");
-                        _exit(EXIT_FAILURE);
-                }
-
-                if (!stdout_is_tty && dup2(fd, STDOUT_FILENO) < 0) {
-                        log_error_errno(errno, "Failed to dup2 /dev/tty: %m");
-                        _exit(EXIT_FAILURE);
-                }
-
-                if (!stderr_is_tty && dup2(fd, STDERR_FILENO) < 0) {
-                        log_error_errno(errno, "Failed to dup2 /dev/tty: %m");
-                        _exit(EXIT_FAILURE);
-                }
-
-                safe_close_above_stdio(fd);
-        }
-
-        (void) rlimit_nofile_safe();
-
-        /* Count arguments */
-        va_start(ap, path);
-        for (n = 0; va_arg(ap, char*); n++)
-                ;
-        va_end(ap);
-
-        /* Allocate strv */
-        l = newa(char*, n + 1);
-
-        /* Fill in arguments */
-        va_start(ap, path);
-        for (i = 0; i <= n; i++)
-                l[i] = va_arg(ap, char*);
-        va_end(ap);
-
-        execv(path, l);
-        _exit(EXIT_FAILURE);
-}
-
 int set_oom_score_adjust(int value) {
         char t[DECIMAL_STR_MAX(int)];
 
-        sprintf(t, "%i", value);
+        xsprintf(t, "%i", value);
 
         return write_string_file("/proc/self/oom_score_adj", t,
                                  WRITE_STRING_FILE_VERIFY_ON_FAILURE|WRITE_STRING_FILE_DISABLE_BUFFER);
index 0e064de85e838572a277f081f98b65d83a18399f..c9536495023855d5e9a363818d2eeac87ba9f160 100644 (file)
@@ -82,8 +82,6 @@ int pid_from_same_root_fs(pid_t pid);
 
 bool is_main_thread(void);
 
-_noreturn_ void freeze(void);
-
 bool oom_score_adjust_is_valid(int oa);
 
 #ifndef PERSONALITY_INVALID
@@ -168,15 +166,13 @@ typedef enum ForkFlags {
         FORK_NEW_USERNS         = 1 << 13, /* Run child in its own user namespace */
 } ForkFlags;
 
-int safe_fork_full(const char *name, const int except_fds[], size_t n_except_fds, ForkFlags flags, pid_t *ret_pid);
+int safe_fork_full(const char *name, int except_fds[], size_t n_except_fds, ForkFlags flags, pid_t *ret_pid);
 
 static inline int safe_fork(const char *name, ForkFlags flags, pid_t *ret_pid) {
         return safe_fork_full(name, NULL, 0, flags, ret_pid);
 }
 
-int namespace_fork(const char *outer_name, const char *inner_name, const int except_fds[], size_t n_except_fds, ForkFlags flags, int pidns_fd, int mntns_fd, int netns_fd, int userns_fd, int root_fd, pid_t *ret_pid);
-
-int fork_agent(const char *name, const int except[], size_t n_except, pid_t *pid, const char *path, ...) _sentinel_;
+int namespace_fork(const char *outer_name, const char *inner_name, int except_fds[], size_t n_except_fds, ForkFlags flags, int pidns_fd, int mntns_fd, int netns_fd, int userns_fd, int root_fd, pid_t *ret_pid);
 
 int set_oom_score_adjust(int value);
 
index 23d108d5df397affe43ad0246258289cc2f654df..1ab41c69741552c57a0b0a59031929b516da28ac 100644 (file)
@@ -300,26 +300,26 @@ int rlimit_parse(int resource, const char *val, struct rlimit *ret) {
 }
 
 int rlimit_format(const struct rlimit *rl, char **ret) {
-        char *s = NULL;
+        _cleanup_free_ char *s = NULL;
+        int r;
 
         assert(rl);
         assert(ret);
 
         if (rl->rlim_cur >= RLIM_INFINITY && rl->rlim_max >= RLIM_INFINITY)
-                s = strdup("infinity");
+                r = free_and_strdup(&s, "infinity");
         else if (rl->rlim_cur >= RLIM_INFINITY)
-                (void) asprintf(&s, "infinity:" RLIM_FMT, rl->rlim_max);
+                r = asprintf(&s, "infinity:" RLIM_FMT, rl->rlim_max);
         else if (rl->rlim_max >= RLIM_INFINITY)
-                (void) asprintf(&s, RLIM_FMT ":infinity", rl->rlim_cur);
+                r = asprintf(&s, RLIM_FMT ":infinity", rl->rlim_cur);
         else if (rl->rlim_cur == rl->rlim_max)
-                (void) asprintf(&s, RLIM_FMT, rl->rlim_cur);
+                r = asprintf(&s, RLIM_FMT, rl->rlim_cur);
         else
-                (void) asprintf(&s, RLIM_FMT ":" RLIM_FMT, rl->rlim_cur, rl->rlim_max);
-
-        if (!s)
+                r = asprintf(&s, RLIM_FMT ":" RLIM_FMT, rl->rlim_cur, rl->rlim_max);
+        if (r < 0)
                 return -ENOMEM;
 
-        *ret = s;
+        *ret = TAKE_PTR(s);
         return 0;
 }
 
index b06b5ce7744d8d444a2561097effdd455cff6398..34b2b279189230a8247abd5db0ee1c62f48c6661 100644 (file)
@@ -265,7 +265,7 @@ int pop_pending_signal_internal(int sig, ...) {
         if (sigemptyset(&ss) < 0)
                 return -errno;
 
-        /* Add first signal (if the signal is zero, we'll silently skip it, to make it easiert to build
+        /* Add first signal (if the signal is zero, we'll silently skip it, to make it easier to build
          * parameter lists where some element are sometimes off, similar to how sigset_add_many_ap() handles
          * this.) */
         if (sig > 0 && sigaddset(&ss, sig) < 0)
index f92e425fd68b738febfd9c57efa269cc09039fba..e857ae4341925fb3c8195b77432a8a11d01c29de 100644 (file)
@@ -245,7 +245,7 @@ struct cmsghdr* cmsg_find(struct msghdr *mh, int level, int type, socklen_t leng
                         _len = sizeof(struct sockaddr_vm);              \
                         break;                                          \
                 default:                                                \
-                        assert_not_reached("invalid socket family");    \
+                        assert_not_reached();                           \
                 }                                                       \
                 _len;                                                   \
         })
index 6dc1e72312c8dfc3b02193e59e2fffbb5df6a5e8..0ed48b3fd4b155fe6ae777e08e474ffdd85b58e8 100644 (file)
@@ -58,7 +58,7 @@ do {                                                                    \
                         (void) va_arg(ap, long double);                 \
                         break;                                          \
                 default:                                                \
-                        assert_not_reached("Unknown format string argument."); \
+                        assert_not_reached();                           \
                 }                                                       \
         }                                                               \
 } while (false)
index 911528fab495a9d761211ccfd8f7116f168a526b..e7654c0c0ff6f09417c4c135e0220016502a5df1 100644 (file)
@@ -233,9 +233,11 @@ int fputstrv(FILE *f, char * const *l, const char *separator, bool *space);
 
 #define strv_free_and_replace(a, b)             \
         ({                                      \
-                strv_free(a);                   \
-                (a) = (b);                      \
-                (b) = NULL;                     \
+                char ***_a = &(a);              \
+                char ***_b = &(b);              \
+                strv_free(*_a);                 \
+                (*_a) = (*_b);                  \
+                (*_b) = NULL;                   \
                 0;                              \
         })
 
index 5d162e8ffe85bf719d2ed103a8e306e94e09d19b..c3b175a192bffd942e6610e4fecb871a1d3af8e9 100644 (file)
@@ -553,14 +553,12 @@ char *format_timespan(char *buf, size_t l, usec_t t, usec_t accuracy) {
 
                 /* Let's see if we should shows this in dot notation */
                 if (t < USEC_PER_MINUTE && b > 0) {
-                        usec_t cc;
-                        signed char j;
+                        signed char j = 0;
 
-                        j = 0;
-                        for (cc = table[i].usec; cc > 1; cc /= 10)
+                        for (usec_t cc = table[i].usec; cc > 1; cc /= 10)
                                 j++;
 
-                        for (cc = accuracy; cc > 1; cc /= 10) {
+                        for (usec_t cc = accuracy; cc > 1; cc /= 10) {
                                 b /= 10;
                                 j--;
                         }
@@ -1334,10 +1332,10 @@ static int get_timezones_from_tzdata_zi(char ***ret) {
                         continue;
 
                 char *tz;
-                if (*type == 'Z' || *type == 'z')
+                if (IN_SET(*type, 'Z', 'z'))
                         /* Zone lines have timezone in field 1. */
                         tz = f1;
-                else if (*type == 'L' || *type == 'l')
+                else if (IN_SET(*type, 'L', 'l'))
                         /* Link lines have timezone in field 2. */
                         tz = f2;
                 else
index 2bd947d6a8da117e13b9d6d2840626c16f168c74..895af8829984437070cdb18e108fa1a164ac9a69 100644 (file)
@@ -111,20 +111,31 @@ usec_t triple_timestamp_by_clock(triple_timestamp *ts, clockid_t clock);
 
 usec_t timespec_load(const struct timespec *ts) _pure_;
 nsec_t timespec_load_nsec(const struct timespec *ts) _pure_;
-struct timespec *timespec_store(struct timespec *ts, usec_t u);
-struct timespec *timespec_store_nsec(struct timespec *ts, nsec_t n);
+struct timespectimespec_store(struct timespec *ts, usec_t u);
+struct timespectimespec_store_nsec(struct timespec *ts, nsec_t n);
 
 usec_t timeval_load(const struct timeval *tv) _pure_;
-struct timeval *timeval_store(struct timeval *tv, usec_t u);
+struct timevaltimeval_store(struct timeval *tv, usec_t u);
 
-char *format_timestamp_style(char *buf, size_t l, usec_t t, TimestampStyle style);
-char *format_timestamp_relative(char *buf, size_t l, usec_t t);
-char *format_timespan(char *buf, size_t l, usec_t t, usec_t accuracy);
+char* format_timestamp_style(char *buf, size_t l, usec_t t, TimestampStyle style) _warn_unused_result_;
+char* format_timestamp_relative(char *buf, size_t l, usec_t t) _warn_unused_result_;
+char* format_timespan(char *buf, size_t l, usec_t t, usec_t accuracy) _warn_unused_result_;
 
-static inline char *format_timestamp(char *buf, size_t l, usec_t t) {
+_warn_unused_result_
+static inline char* format_timestamp(char *buf, size_t l, usec_t t) {
         return format_timestamp_style(buf, l, t, TIMESTAMP_PRETTY);
 }
 
+/* Note: the lifetime of the compound literal is the immediately surrounding block,
+ * see C11 §6.5.2.5, and
+ * https://stackoverflow.com/questions/34880638/compound-literal-lifetime-and-if-blocks */
+#define FORMAT_TIMESTAMP(t) format_timestamp((char[FORMAT_TIMESTAMP_MAX]){}, FORMAT_TIMESTAMP_MAX, t)
+#define FORMAT_TIMESTAMP_RELATIVE(t)                                    \
+        format_timestamp_relative((char[FORMAT_TIMESTAMP_RELATIVE_MAX]){}, FORMAT_TIMESTAMP_RELATIVE_MAX, t)
+#define FORMAT_TIMESPAN(t, accuracy) format_timespan((char[FORMAT_TIMESPAN_MAX]){}, FORMAT_TIMESPAN_MAX, t, accuracy)
+#define FORMAT_TIMESTAMP_STYLE(t, style) \
+        format_timestamp_style((char[FORMAT_TIMESTAMP_MAX]){}, FORMAT_TIMESTAMP_MAX, t, style)
+
 int parse_timestamp(const char *t, usec_t *usec);
 
 int parse_sec(const char *t, usec_t *usec);
@@ -156,9 +167,8 @@ usec_t jiffies_to_usec(uint32_t jiffies);
 bool in_utc_timezone(void);
 
 static inline usec_t usec_add(usec_t a, usec_t b) {
-
-        /* Adds two time values, and makes sure USEC_INFINITY as input results as USEC_INFINITY in output, and doesn't
-         * overflow. */
+        /* Adds two time values, and makes sure USEC_INFINITY as input results as USEC_INFINITY in output,
+         * and doesn't overflow. */
 
         if (a > USEC_INFINITY - b) /* overflow check */
                 return USEC_INFINITY;
@@ -167,7 +177,6 @@ static inline usec_t usec_add(usec_t a, usec_t b) {
 }
 
 static inline usec_t usec_sub_unsigned(usec_t timestamp, usec_t delta) {
-
         if (timestamp == USEC_INFINITY) /* Make sure infinity doesn't degrade */
                 return USEC_INFINITY;
         if (timestamp < delta)
@@ -184,14 +193,14 @@ static inline usec_t usec_sub_signed(usec_t timestamp, int64_t delta) {
 }
 
 #if SIZEOF_TIME_T == 8
-/* The last second we can format is 31. Dec 9999, 1s before midnight, because otherwise we'd enter 5 digit year
* territory. However, since we want to stay away from this in all timezones we take one day off. */
-#define USEC_TIMESTAMP_FORMATTABLE_MAX ((usec_t) 253402214399000000)
+  /* The last second we can format is 31. Dec 9999, 1s before midnight, because otherwise we'd enter 5 digit
  * year territory. However, since we want to stay away from this in all timezones we take one day off. */
+#  define USEC_TIMESTAMP_FORMATTABLE_MAX ((usec_t) 253402214399000000)
 #elif SIZEOF_TIME_T == 4
 /* With a 32bit time_t we can't go beyond 2038... */
-#define USEC_TIMESTAMP_FORMATTABLE_MAX ((usec_t) 2147483647000000)
+#  define USEC_TIMESTAMP_FORMATTABLE_MAX ((usec_t) 2147483647000000)
 #else
-#error "Yuck, time_t is neither 4 nor 8 bytes wide?"
+#  error "Yuck, time_t is neither 4 nor 8 bytes wide?"
 #endif
 
 int time_change_fd(void);
index 284a773483165875eca5878d1345f64f613125b7..1deead74588b0a9ab4033931426fa30622f98b22 100644 (file)
@@ -378,12 +378,13 @@ int unit_name_unescape(const char *f, char **ret) {
 }
 
 int unit_name_path_escape(const char *f, char **ret) {
-        char *p, *s;
+        _cleanup_free_ char *p = NULL;
+        char *s;
 
         assert(f);
         assert(ret);
 
-        p = strdupa(f);
+        p = strdup(f);
         if (!p)
                 return -ENOMEM;
 
@@ -395,13 +396,9 @@ int unit_name_path_escape(const char *f, char **ret) {
                 if (!path_is_normalized(p))
                         return -EINVAL;
 
-                /* Truncate trailing slashes */
+                /* Truncate trailing slashes and skip leading slashes */
                 delete_trailing_chars(p, "/");
-
-                /* Truncate leading slashes */
-                p = skip_leading_chars(p, "/");
-
-                s = unit_name_escape(p);
+                s = unit_name_escape(skip_leading_chars(p, "/"));
         }
         if (!s)
                 return -ENOMEM;
@@ -531,7 +528,7 @@ int unit_name_from_path(const char *path, const char *suffix, char **ret) {
         if (strlen(s) >= UNIT_NAME_MAX) /* Return a slightly more descriptive error for this specific condition */
                 return -ENAMETOOLONG;
 
-        /* Refuse this if this got too long or for some other reason didn't result in a valid name */
+        /* Refuse if this for some other reason didn't result in a valid name */
         if (!unit_name_is_valid(s, UNIT_NAME_PLAIN))
                 return -EINVAL;
 
@@ -565,7 +562,7 @@ int unit_name_from_path_instance(const char *prefix, const char *path, const cha
         if (strlen(s) >= UNIT_NAME_MAX) /* Return a slightly more descriptive error for this specific condition */
                 return -ENAMETOOLONG;
 
-        /* Refuse this if this got too long or for some other reason didn't result in a valid name */
+        /* Refuse if this for some other reason didn't result in a valid name */
         if (!unit_name_is_valid(s, UNIT_NAME_INSTANCE))
                 return -EINVAL;
 
index 29530bb691c6c22c398a3067836ea6c4c7a0a0ed..bf1861981a3aa6816180289827ed036588132f56 100644 (file)
@@ -174,7 +174,7 @@ static int parse_argv(int argc, char *argv[]) {
                         return -EINVAL;
 
                 default:
-                        assert_not_reached("Unhandled option");
+                        assert_not_reached();
                 }
 
         if ((arg_unregister || arg_cat_config) && argc > optind)
index 3fc319ca27325391214472a0b42ca6476dda0e3e..7d5a52841ee107190ba4fd47d8d7fd98f0fd55bb 100644 (file)
@@ -89,7 +89,7 @@ static int parse_argv(int argc, char *argv[]) {
                         return -EINVAL;
 
                 default:
-                        assert_not_reached("Unknown option");
+                        assert_not_reached();
                 }
 
         return 1;
index cb4f758cb41603eb463d7ccb95d21202170d51a4..78642063c4a61c7fc4198d13d03e81077c384782 100644 (file)
@@ -67,7 +67,7 @@ static int parse_argv(int argc, char *argv[]) {
                         return -EINVAL;
 
                 default:
-                        assert_not_reached("Unknown option");
+                        assert_not_reached();
                 }
 
         return 1;
index df8b0542c9d2a00799a9f0a000bb6fbd8392bc30..264189c36b93957af37bd1347ff9a7acd6268001 100644 (file)
@@ -65,6 +65,7 @@ static const char *arg_dollar_boot_path(void) {
 
 static int acquire_esp(
                 bool unprivileged_mode,
+                bool graceful,
                 uint32_t *ret_part,
                 uint64_t *ret_pstart,
                 uint64_t *ret_psize,
@@ -80,10 +81,14 @@ static int acquire_esp(
          * this). */
 
         r = find_esp_and_warn(arg_esp_path, unprivileged_mode, &np, ret_part, ret_pstart, ret_psize, ret_uuid);
-        if (r == -ENOKEY)
+        if (r == -ENOKEY) {
+                if (graceful)
+                        return log_info_errno(r, "Couldn't find EFI system partition, skipping.");
+
                 return log_error_errno(r,
                                        "Couldn't find EFI system partition. It is recommended to mount it to /boot or /efi.\n"
                                        "Alternatively, use --esp-path= to specify path to mount point.");
+        }
         if (r < 0)
                 return r;
 
@@ -500,7 +505,7 @@ static int version_check(int fd_from, const char *from, int fd_to, const char *t
         if (r < 0)
                 return r;
         if (r == 0)
-                return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
+                return log_notice_errno(SYNTHETIC_ERRNO(EREMOTE),
                                        "Source file \"%s\" does not carry version information!",
                                        from);
 
@@ -508,12 +513,15 @@ static int version_check(int fd_from, const char *from, int fd_to, const char *t
         if (r < 0)
                 return r;
         if (r == 0 || compare_product(a, b) != 0)
-                return log_notice_errno(SYNTHETIC_ERRNO(EEXIST),
+                return log_notice_errno(SYNTHETIC_ERRNO(EREMOTE),
                                         "Skipping \"%s\", since it's owned by another boot loader.",
                                         to);
 
-        if (compare_version(a, b) < 0)
-                return log_warning_errno(SYNTHETIC_ERRNO(ESTALE), "Skipping \"%s\", since a newer boot loader version exists already.", to);
+        r = compare_version(a, b);
+        if (r < 0)
+                return log_warning_errno(SYNTHETIC_ERRNO(ESTALE), "Skipping \"%s\", since newer boot loader version in place already.", to);
+        else if (r == 0)
+                return log_info_errno(SYNTHETIC_ERRNO(ESTALE), "Skipping \"%s\", since same boot loader version in place already.", to);
 
         return 0;
 }
@@ -665,6 +673,10 @@ static int install_binaries(const char *esp_path, bool force) {
                         continue;
 
                 k = copy_one_file(esp_path, de->d_name, force);
+                /* Don't propagate an error code if no update necessary, installed version already equal or
+                 * newer version, or other boot loader in place. */
+                if (arg_graceful && IN_SET(k, -ESTALE, -EREMOTE))
+                        continue;
                 if (k < 0 && r == 0)
                         r = k;
         }
@@ -1216,7 +1228,7 @@ static int parse_argv(int argc, char *argv[]) {
                         return -EINVAL;
 
                 default:
-                        assert_not_reached("Unknown option");
+                        assert_not_reached();
                 }
 
         return 1;
@@ -1243,7 +1255,7 @@ static int verb_status(int argc, char *argv[], void *userdata) {
         sd_id128_t esp_uuid = SD_ID128_NULL, xbootldr_uuid = SD_ID128_NULL;
         int r, k;
 
-        r = acquire_esp(geteuid() != 0, NULL, NULL, NULL, &esp_uuid);
+        r = acquire_esp(/* unprivileged_mode= */ geteuid() != 0, /* graceful= */ false, NULL, NULL, NULL, &esp_uuid);
         if (arg_print_esp_path) {
                 if (r == -EACCES) /* If we couldn't acquire the ESP path, log about access errors (which is the only
                                    * error the find_esp_and_warn() won't log on its own) */
@@ -1254,7 +1266,7 @@ static int verb_status(int argc, char *argv[], void *userdata) {
                 puts(arg_esp_path);
         }
 
-        r = acquire_xbootldr(geteuid() != 0, &xbootldr_uuid);
+        r = acquire_xbootldr(/* unprivileged_mode= */ geteuid() != 0, &xbootldr_uuid);
         if (arg_print_dollar_boot_path) {
                 if (r == -EACCES)
                         return log_error_errno(r, "Failed to determine XBOOTLDR location: %m");
@@ -1337,7 +1349,7 @@ static int verb_status(int argc, char *argv[], void *userdata) {
                 sd_id128_t bootloader_esp_uuid;
                 bool have_bootloader_esp_uuid = efi_loader_get_device_part_uuid(&bootloader_esp_uuid) >= 0;
 
-                print_yes_no_line(false, have_bootloader_esp_uuid, "Boot loader sets ESP partition information");
+                print_yes_no_line(false, have_bootloader_esp_uuid, "Boot loader sets ESP information");
                 if (have_bootloader_esp_uuid && !sd_id128_equal(esp_uuid, bootloader_esp_uuid))
                         printf("WARNING: The boot loader reports a different ESP UUID than detected!\n");
 
@@ -1402,13 +1414,13 @@ static int verb_list(int argc, char *argv[], void *userdata) {
          * off logging about access errors and turn off potentially privileged device probing. Here we're interested in
          * the latter but not the former, hence request the mode, and log about EACCES. */
 
-        r = acquire_esp(geteuid() != 0, NULL, NULL, NULL, NULL);
+        r = acquire_esp(/* unprivileged_mode= */ geteuid() != 0, /* graceful= */ false, NULL, NULL, NULL, NULL);
         if (r == -EACCES) /* We really need the ESP path for this call, hence also log about access errors */
                 return log_error_errno(r, "Failed to determine ESP: %m");
         if (r < 0)
                 return r;
 
-        r = acquire_xbootldr(geteuid() != 0, NULL);
+        r = acquire_xbootldr(/* unprivileged_mode= */ geteuid() != 0, NULL);
         if (r == -EACCES)
                 return log_error_errno(r, "Failed to determine XBOOTLDR partition: %m");
         if (r < 0)
@@ -1600,21 +1612,24 @@ static int verb_install(int argc, char *argv[], void *userdata) {
         sd_id128_t uuid = SD_ID128_NULL;
         uint64_t pstart = 0, psize = 0;
         uint32_t part = 0;
-        bool install;
+        bool install, graceful;
         int r;
 
-        r = acquire_esp(false, &part, &pstart, &psize, &uuid);
+        install = streq(argv[0], "install");
+        graceful = !install && arg_graceful; /* support graceful mode for updates */
+
+        r = acquire_esp(/* unprivileged_mode= */ false, graceful, &part, &pstart, &psize, &uuid);
+        if (graceful && r == -ENOKEY)
+                return 0; /* If --graceful is specified and we can't find an ESP, handle this cleanly */
         if (r < 0)
                 return r;
 
-        r = acquire_xbootldr(false, NULL);
+        r = acquire_xbootldr(/* unprivileged_mode= */ false, NULL);
         if (r < 0)
                 return r;
 
         settle_make_machine_id_directory();
 
-        install = streq(argv[0], "install");
-
         RUN_WITH_UMASK(0002) {
                 if (install) {
                         /* Don't create any of these directories when we are just updating. When we update
@@ -1663,11 +1678,11 @@ static int verb_remove(int argc, char *argv[], void *userdata) {
         sd_id128_t uuid = SD_ID128_NULL;
         int r, q;
 
-        r = acquire_esp(false, NULL, NULL, NULL, &uuid);
+        r = acquire_esp(/* unprivileged_mode= */ false, /* graceful= */ false, NULL, NULL, NULL, &uuid);
         if (r < 0)
                 return r;
 
-        r = acquire_xbootldr(false, NULL);
+        r = acquire_xbootldr(/* unprivileged_mode= */ false, NULL);
         if (r < 0)
                 return r;
 
@@ -1726,7 +1741,7 @@ static int verb_is_installed(int argc, char *argv[], void *userdata) {
         _cleanup_free_ char *p = NULL;
         int r;
 
-        r = acquire_esp(false, NULL, NULL, NULL, NULL);
+        r = acquire_esp(/* privileged_mode= */ false, /* graceful= */ false, NULL, NULL, NULL, NULL);
         if (r < 0)
                 return r;
 
index afdf739d9b7c0d190df1282aff0f13b378eb0601..0a96a72d6ecce87ce9d334f36e20e29670d5d9dd 100644 (file)
@@ -71,14 +71,14 @@ if conf.get('ENABLE_EFI') == 1 and get_option('gnu-efi') != 'false'
         efi_libdir = get_option('efi-libdir')
         if efi_libdir == ''
                 # New location first introduced with gnu-efi 3.0.11
-                efi_libdir = join_paths('/usr/lib/gnuefi', EFI_MACHINE_TYPE_NAME)
+                efi_libdir = '/usr/lib/gnuefi' / EFI_MACHINE_TYPE_NAME
                 cmd = run_command(test, '-e', efi_libdir)
 
                 if cmd.returncode() != 0
                         # Fall back to the old approach
                         cmd = run_command(efi_cc + ['-print-multi-os-directory'])
                         if cmd.returncode() == 0
-                                path = join_paths('/usr/lib', cmd.stdout().strip())
+                                path = '/usr/lib' / cmd.stdout().strip()
                                 cmd = run_command(env, 'realpath', '-e', path)
                                 if cmd.returncode() == 0
                                         efi_libdir = cmd.stdout().strip()
@@ -115,7 +115,7 @@ if have_gnu_efi
                             ['sbat-distro-url', 'BUG_REPORT_URL']]
                 foreach sbatvar : sbatvars
                         value = get_option(sbatvar[0])
-                        if value == '' or value == 'auto'
+                        if (value == '' and not meson.is_cross_build()) or value == 'auto'
                                 cmd = 'if [ -e /etc/os-release ]; then . /etc/os-release; else . /usr/lib/os-release; fi; echo $@0@'.format(sbatvar[1])
                                 value = run_command(sh, '-c', cmd).stdout().strip()
                                 message('@0@ (from @1@): @2@'.format(sbatvar[0], sbatvar[1], value))
@@ -148,13 +148,13 @@ if have_gnu_efi
 
         efi_location_map = [
                 # New locations first introduced with gnu-efi 3.0.11
-                [join_paths(efi_libdir, 'efi.lds'),
-                 join_paths(efi_libdir, 'crt0.o')],
+                [efi_libdir / 'efi.lds',
+                 efi_libdir / 'crt0.o'],
                 # Older locations...
-                [join_paths(efi_libdir, 'gnuefi', 'elf_@0@_efi.lds'.format(gnu_efi_path_arch)),
-                 join_paths(efi_libdir, 'gnuefi', 'crt0-efi-@0@.o'.format(gnu_efi_path_arch))],
-                [join_paths(efi_libdir, 'elf_@0@_efi.lds'.format(gnu_efi_path_arch)),
-                 join_paths(efi_libdir, 'crt0-efi-@0@.o'.format(gnu_efi_path_arch))]]
+                [efi_libdir / 'gnuefi' / 'elf_@0@_efi.lds'.format(gnu_efi_path_arch),
+                 efi_libdir / 'gnuefi' / 'crt0-efi-@0@.o'.format(gnu_efi_path_arch)],
+                [efi_libdir / 'elf_@0@_efi.lds'.format(gnu_efi_path_arch),
+                 efi_libdir / 'crt0-efi-@0@.o'.format(gnu_efi_path_arch)]]
         efi_lds = ''
         foreach location : efi_location_map
                 if efi_lds == ''
@@ -191,7 +191,7 @@ if have_gnu_efi
                 '-nostdlib',
                 '-std=gnu99',
                 '-isystem', efi_incdir,
-                '-isystem', join_paths(efi_incdir, gnu_efi_path_arch),
+                '-isystem', efi_incdir / gnu_efi_path_arch,
                 '-I', fundamental_path,
                 '-DSD_BOOT',
                 '-include', efi_config_h,
index 89b32f4c73fddd1864ef1b89594b27723a3cbc04..4dbb11f15b935d1a895e6cb08b78c9d62e3c8921 100644 (file)
@@ -147,7 +147,7 @@ static int parse_xml_annotation(Context *context, uint64_t *flags) {
                         break;
 
                 default:
-                        assert_not_reached("Bad state");
+                        assert_not_reached();
                 }
         }
 }
index 8aa769e0f9232ca1b0bf0449b9169648d76feeaa..b9d84c9e58647220644e4f3cc06ac9f8b275b066 100644 (file)
@@ -121,7 +121,7 @@ static int acquire_bus(bool set_monitor, sd_bus **ret) {
                         break;
 
                 default:
-                        assert_not_reached("Hmm, unknown transport type.");
+                        assert_not_reached();
                 }
         }
         if (r < 0)
@@ -718,7 +718,7 @@ static int format_cmdline(sd_bus_message *m, FILE *f, bool needs_space) {
                         break;
 
                 default:
-                        assert_not_reached("Unknown basic type.");
+                        assert_not_reached();
                 }
 
                 needs_space = true;
@@ -1957,7 +1957,7 @@ static int json_transform_one(sd_bus_message *m, JsonVariant **ret) {
                 break;
 
         default:
-                assert_not_reached("Unexpected element type");
+                assert_not_reached();
         }
 
         *ret = TAKE_PTR(v);
@@ -2525,7 +2525,7 @@ static int parse_argv(int argc, char *argv[]) {
                         return -EINVAL;
 
                 default:
-                        assert_not_reached("Unhandled option");
+                        assert_not_reached();
                 }
 
         return 1;
index f39aa53da0b9123e3deec4fa064449e10abef223..ab5f153d9df1c51f15093f3875aadb4ef61e018a 100644 (file)
@@ -141,7 +141,7 @@ static int parse_argv(int argc, char *argv[]) {
                         return -EINVAL;
 
                 default:
-                        assert_not_reached("Unhandled option");
+                        assert_not_reached();
                 }
 
         if (arg_machine && arg_show_unit != SHOW_UNIT_NONE)
index 9cc2f275918a22f458f7aac9c1fd24d184c2dc19..0104b6a543b80baeb61afc3282a617f867443b29 100644 (file)
@@ -101,6 +101,10 @@ static const char *maybe_format_timespan(char *buf, size_t l, usec_t t, usec_t a
         return format_timespan(buf, l, t, accuracy);
 }
 
+#define BUFSIZE1 CONST_MAX(FORMAT_TIMESPAN_MAX, DECIMAL_STR_MAX(usec_t))
+#define MAYBE_FORMAT_TIMESPAN(t, accuracy) \
+        maybe_format_timespan((char[BUFSIZE1]){}, BUFSIZE1, t, accuracy)
+
 static const char *maybe_format_bytes(char *buf, size_t l, bool is_valid, uint64_t t) {
         if (!is_valid)
                 return "-";
@@ -111,6 +115,10 @@ static const char *maybe_format_bytes(char *buf, size_t l, bool is_valid, uint64
         return format_bytes(buf, l, t);
 }
 
+#define BUFSIZE2 CONST_MAX(FORMAT_BYTES_MAX, DECIMAL_STR_MAX(uint64_t))
+#define MAYBE_FORMAT_BYTES(is_valid, t) \
+        maybe_format_bytes((char[BUFSIZE2]){}, BUFSIZE2, is_valid, t)
+
 static bool is_root_cgroup(const char *path) {
 
         /* Returns true if the specified path belongs to the root cgroup. The root cgroup is special on cgroup v2 as it
@@ -595,8 +603,7 @@ static void display(Hashmap *a) {
         Group *g;
         Group **array;
         signed path_columns;
-        unsigned rows, n = 0, j, maxtcpu = 0, maxtpath = 3; /* 3 for ellipsize() to work properly */
-        char buffer[MAX4(21U, FORMAT_BYTES_MAX, FORMAT_TIMESPAN_MAX, DECIMAL_STR_MAX(usec_t))];
+        unsigned rows, n = 0, maxtcpu = 0, maxtpath = 3; /* 3 for ellipsize() to work properly */
 
         assert(a);
 
@@ -612,43 +619,38 @@ static void display(Hashmap *a) {
         typesafe_qsort(array, n, group_compare);
 
         /* Find the longest names in one run */
-        for (j = 0; j < n; j++) {
-                unsigned cputlen, pathtlen;
-
-                maybe_format_timespan(buffer, sizeof(buffer), (usec_t) (array[j]->cpu_usage / NSEC_PER_USEC), 0);
-                cputlen = strlen(buffer);
-                maxtcpu = MAX(maxtcpu, cputlen);
-
-                pathtlen = strlen(array[j]->path);
-                maxtpath = MAX(maxtpath, pathtlen);
+        for (unsigned j = 0; j < n; j++) {
+                maxtcpu = MAX(maxtcpu,
+                              strlen(MAYBE_FORMAT_TIMESPAN((usec_t) (array[j]->cpu_usage / NSEC_PER_USEC), 0)));
+                maxtpath = MAX(maxtpath,
+                               strlen(array[j]->path));
         }
 
-        if (arg_cpu_type == CPU_PERCENT)
-                xsprintf(buffer, "%6s", "%CPU");
-        else
-                xsprintf(buffer, "%*s", maxtcpu, "CPU Time");
-
         rows = lines();
         if (rows <= 10)
                 rows = 10;
 
         if (on_tty()) {
                 const char *on, *off;
+                unsigned cpu_len = arg_cpu_type == CPU_PERCENT ? 6 : maxtcpu;
 
-                path_columns = columns() - 36 - strlen(buffer);
+                path_columns = columns() - 36 - cpu_len;
                 if (path_columns < 10)
                         path_columns = 10;
 
                 on = ansi_highlight_underline();
                 off = ansi_underline();
 
-                printf("%s%s%-*s%s %s%7s%s %s%s%s %s%8s%s %s%8s%s %s%8s%s%s\n",
+                printf("%s%s%-*s%s %s%7s%s %s%*s%s %s%8s%s %s%8s%s %s%8s%s%s\n",
                        ansi_underline(),
                        arg_order == ORDER_PATH ? on : "", path_columns, "Control Group",
                        arg_order == ORDER_PATH ? off : "",
-                       arg_order == ORDER_TASKS ? on : "", arg_count == COUNT_PIDS ? "Tasks" : arg_count == COUNT_USERSPACE_PROCESSES ? "Procs" : "Proc+",
+                       arg_order == ORDER_TASKS ? on : "",
+                       arg_count == COUNT_PIDS ? "Tasks" : arg_count == COUNT_USERSPACE_PROCESSES ? "Procs" : "Proc+",
                        arg_order == ORDER_TASKS ? off : "",
-                       arg_order == ORDER_CPU ? on : "", buffer,
+                       arg_order == ORDER_CPU ? on : "",
+                       cpu_len,
+                       arg_cpu_type == CPU_PERCENT ? "%CPU" : "CPU Time",
                        arg_order == ORDER_CPU ? off : "",
                        arg_order == ORDER_MEMORY ? on : "", "Memory",
                        arg_order == ORDER_MEMORY ? off : "",
@@ -660,7 +662,7 @@ static void display(Hashmap *a) {
         } else
                 path_columns = maxtpath;
 
-        for (j = 0; j < n; j++) {
+        for (unsigned j = 0; j < n; j++) {
                 _cleanup_free_ char *ellipsized = NULL;
                 const char *path;
 
@@ -684,11 +686,11 @@ static void display(Hashmap *a) {
                         else
                                 fputs("      -", stdout);
                 } else
-                        printf(" %*s", maxtcpu, maybe_format_timespan(buffer, sizeof(buffer), (usec_t) (g->cpu_usage / NSEC_PER_USEC), 0));
+                        printf(" %*s", maxtcpu, MAYBE_FORMAT_TIMESPAN((usec_t) (g->cpu_usage / NSEC_PER_USEC), 0));
 
-                printf(" %8s", maybe_format_bytes(buffer, sizeof(buffer), g->memory_valid, g->memory));
-                printf(" %8s", maybe_format_bytes(buffer, sizeof(buffer), g->io_valid, g->io_input_bps));
-                printf(" %8s", maybe_format_bytes(buffer, sizeof(buffer), g->io_valid, g->io_output_bps));
+                printf(" %8s", MAYBE_FORMAT_BYTES(g->memory_valid, g->memory));
+                printf(" %8s", MAYBE_FORMAT_BYTES(g->io_valid, g->io_input_bps));
+                printf(" %8s", MAYBE_FORMAT_BYTES(g->io_valid, g->io_output_bps));
 
                 putchar('\n');
         }
@@ -883,7 +885,7 @@ static int parse_argv(int argc, char *argv[]) {
                         return -EINVAL;
 
                 default:
-                        assert_not_reached("Unhandled option");
+                        assert_not_reached();
                 }
 
         if (optind == argc - 1)
@@ -949,7 +951,6 @@ static int run(int argc, char *argv[]) {
         while (!quit) {
                 usec_t t;
                 char key;
-                char h[FORMAT_TIMESPAN_MAX];
 
                 t = now(CLOCK_MONOTONIC);
 
@@ -1055,7 +1056,7 @@ static int run(int argc, char *argv[]) {
                 case '+':
                         arg_delay = usec_add(arg_delay, arg_delay < USEC_PER_SEC ? USEC_PER_MSEC * 250 : USEC_PER_SEC);
 
-                        fprintf(stdout, "\nIncreased delay to %s.", format_timespan(h, sizeof(h), arg_delay, 0));
+                        fprintf(stdout, "\nIncreased delay to %s.", FORMAT_TIMESPAN(arg_delay, 0));
                         fflush(stdout);
                         sleep(1);
                         break;
@@ -1066,7 +1067,7 @@ static int run(int argc, char *argv[]) {
                         else
                                 arg_delay = usec_sub_unsigned(arg_delay, arg_delay < USEC_PER_MSEC * 1250 ? USEC_PER_MSEC * 250 : USEC_PER_SEC);
 
-                        fprintf(stdout, "\nDecreased delay to %s.", format_timespan(h, sizeof(h), arg_delay, 0));
+                        fprintf(stdout, "\nDecreased delay to %s.", FORMAT_TIMESPAN(arg_delay, 0));
                         fflush(stdout);
                         sleep(1);
                         break;
index edc958816532b2a8d4845210e23b75c108ab1687..30226b9bde6cbe556172a345c399f381235bab82 100644 (file)
@@ -305,7 +305,6 @@ static int automount_coldplug(Unit *u) {
 }
 
 static void automount_dump(Unit *u, FILE *f, const char *prefix) {
-        char time_string[FORMAT_TIMESPAN_MAX];
         Automount *a = AUTOMOUNT(u);
 
         assert(a);
@@ -320,7 +319,7 @@ static void automount_dump(Unit *u, FILE *f, const char *prefix) {
                 prefix, automount_result_to_string(a->result),
                 prefix, a->where,
                 prefix, a->directory_mode,
-                prefix, format_timespan(time_string, FORMAT_TIMESPAN_MAX, a->timeout_idle_usec, USEC_PER_SEC));
+                prefix, FORMAT_TIMESPAN(a->timeout_idle_usec, USEC_PER_SEC));
 }
 
 static void automount_enter_dead(Automount *a, AutomountResult f) {
@@ -1066,11 +1065,11 @@ static bool automount_supported(void) {
 }
 
 static const char* const automount_result_table[_AUTOMOUNT_RESULT_MAX] = {
-        [AUTOMOUNT_SUCCESS] = "success",
-        [AUTOMOUNT_FAILURE_RESOURCES] = "resources",
-        [AUTOMOUNT_FAILURE_START_LIMIT_HIT] = "start-limit-hit",
+        [AUTOMOUNT_SUCCESS]                       = "success",
+        [AUTOMOUNT_FAILURE_RESOURCES]             = "resources",
+        [AUTOMOUNT_FAILURE_START_LIMIT_HIT]       = "start-limit-hit",
         [AUTOMOUNT_FAILURE_MOUNT_START_LIMIT_HIT] = "mount-start-limit-hit",
-        [AUTOMOUNT_FAILURE_UNMOUNTED] = "unmounted",
+        [AUTOMOUNT_FAILURE_UNMOUNTED]             = "unmounted",
 };
 
 DEFINE_STRING_TABLE_LOOKUP(automount_result, AutomountResult);
index 2cbb78997869e2291d47b67031fba488ea4c7364..e5fd6672bb3482d6cdf97e9555497e20746f0870 100644 (file)
@@ -394,8 +394,6 @@ void cgroup_context_dump(Unit *u, FILE* f, const char *prefix) {
         CGroupSocketBindItem *bi;
         IPAddressAccessItem *iaai;
         char **path;
-        char q[FORMAT_TIMESPAN_MAX];
-        char v[FORMAT_TIMESPAN_MAX];
 
         char cda[FORMAT_CGROUP_DIFF_MAX];
         char cdb[FORMAT_CGROUP_DIFF_MAX];
@@ -460,8 +458,8 @@ void cgroup_context_dump(Unit *u, FILE* f, const char *prefix) {
                 prefix, c->startup_cpu_weight,
                 prefix, c->cpu_shares,
                 prefix, c->startup_cpu_shares,
-                prefix, format_timespan(q, sizeof(q), c->cpu_quota_per_sec_usec, 1),
-                prefix, format_timespan(v, sizeof(v), c->cpu_quota_period_usec, 1),
+                prefix, FORMAT_TIMESPAN(c->cpu_quota_per_sec_usec, 1),
+                prefix, FORMAT_TIMESPAN(c->cpu_quota_period_usec, 1),
                 prefix, strempty(cpuset_cpus),
                 prefix, strempty(cpuset_mems),
                 prefix, c->io_weight,
@@ -514,11 +512,9 @@ void cgroup_context_dump(Unit *u, FILE* f, const char *prefix) {
                         "%sIODeviceLatencyTargetSec: %s %s\n",
                         prefix,
                         l->path,
-                        format_timespan(q, sizeof(q), l->target_usec, 1));
-
-        LIST_FOREACH(device_limits, il, c->io_device_limits) {
-                char buf[FORMAT_BYTES_MAX];
+                        FORMAT_TIMESPAN(l->target_usec, 1));
 
+        LIST_FOREACH(device_limits, il, c->io_device_limits)
                 for (CGroupIOLimitType type = 0; type < _CGROUP_IO_LIMIT_TYPE_MAX; type++)
                         if (il->limits[type] != cgroup_io_limit_defaults[type])
                                 fprintf(f,
@@ -526,8 +522,7 @@ void cgroup_context_dump(Unit *u, FILE* f, const char *prefix) {
                                         prefix,
                                         cgroup_io_limit_type_to_string(type),
                                         il->path,
-                                        format_bytes(buf, sizeof(buf), il->limits[type]));
-        }
+                                        FORMAT_BYTES(il->limits[type]));
 
         LIST_FOREACH(device_weights, w, c->blockio_device_weights)
                 fprintf(f,
@@ -537,20 +532,18 @@ void cgroup_context_dump(Unit *u, FILE* f, const char *prefix) {
                         w->weight);
 
         LIST_FOREACH(device_bandwidths, b, c->blockio_device_bandwidths) {
-                char buf[FORMAT_BYTES_MAX];
-
                 if (b->rbps != CGROUP_LIMIT_MAX)
                         fprintf(f,
                                 "%sBlockIOReadBandwidth: %s %s\n",
                                 prefix,
                                 b->path,
-                                format_bytes(buf, sizeof(buf), b->rbps));
+                                FORMAT_BYTES(b->rbps));
                 if (b->wbps != CGROUP_LIMIT_MAX)
                         fprintf(f,
                                 "%sBlockIOWriteBandwidth: %s %s\n",
                                 prefix,
                                 b->path,
-                                format_bytes(buf, sizeof(buf), b->wbps));
+                                FORMAT_BYTES(b->wbps));
         }
 
         LIST_FOREACH(items, iaai, c->ip_address_allow) {
@@ -869,10 +862,9 @@ static usec_t cgroup_cpu_adjust_period_and_log(Unit *u, usec_t period, usec_t qu
         new_period = cgroup_cpu_adjust_period(period, quota, USEC_PER_MSEC, USEC_PER_SEC);
 
         if (new_period != period) {
-                char v[FORMAT_TIMESPAN_MAX];
                 log_unit_full(u, u->warned_clamping_cpu_quota_period ? LOG_DEBUG : LOG_WARNING,
                               "Clamping CPU interval for cpu.max: period is now %s",
-                              format_timespan(v, sizeof(v), new_period, 1));
+                              FORMAT_TIMESPAN(new_period, 1));
                 u->warned_clamping_cpu_quota_period = true;
         }
 
index 84c3caf3a5b293c0c87faa30f8600610335ae0c2..77fbca8389061c0bbe548e1f3de1f81d2d3ba36f 100644 (file)
@@ -1114,12 +1114,10 @@ int bus_cgroup_set_property(
                         unit_invalidate_cgroup(u, CGROUP_MASK_CPU);
                         if (c->cpu_quota_period_usec == USEC_INFINITY)
                                 unit_write_setting(u, flags, "CPUQuotaPeriodSec", "CPUQuotaPeriodSec=");
-                        else {
-                                char v[FORMAT_TIMESPAN_MAX];
+                        else
                                 unit_write_settingf(u, flags, "CPUQuotaPeriodSec",
                                                     "CPUQuotaPeriodSec=%s",
-                                                    format_timespan(v, sizeof(v), c->cpu_quota_period_usec, 1));
-                        }
+                                                    FORMAT_TIMESPAN(c->cpu_quota_period_usec, 1));
                 }
 
                 return 1;
@@ -1374,7 +1372,6 @@ int bus_cgroup_set_property(
                 if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
                         _cleanup_free_ char *buf = NULL;
                         _cleanup_fclose_ FILE *f = NULL;
-                        char ts[FORMAT_TIMESPAN_MAX];
                         CGroupIODeviceLatency *a;
                         size_t size = 0;
 
@@ -1392,7 +1389,7 @@ int bus_cgroup_set_property(
                         fputs("IODeviceLatencyTargetSec=\n", f);
                         LIST_FOREACH(device_latencies, a, c->io_device_latencies)
                                 fprintf(f, "IODeviceLatencyTargetSec=%s %s\n",
-                                        a->path, format_timespan(ts, sizeof(ts), a->target_usec, 1));
+                                        a->path, FORMAT_TIMESPAN(a->target_usec, 1));
 
                         r = fflush_and_check(f);
                         if (r < 0)
index de057a024529ab5afb7eded1b21c968f2c2b130b..1f2ac8152c2f2867d19384d5a5f335837c1a38cf 100644 (file)
@@ -1324,16 +1324,14 @@ static int verify_run_space(const char *message, sd_bus_error *error) {
 
         available = (uint64_t) svfs.f_bfree * (uint64_t) svfs.f_bsize;
 
-        if (available < RELOAD_DISK_SPACE_MIN) {
-                char fb_available[FORMAT_BYTES_MAX], fb_need[FORMAT_BYTES_MAX];
+        if (available < RELOAD_DISK_SPACE_MIN)
                 return sd_bus_error_setf(error,
                                          BUS_ERROR_DISK_FULL,
                                          "%s, not enough space available on /run/systemd. "
                                          "Currently, %s are free, but a safety buffer of %s is enforced.",
                                          message,
-                                         format_bytes(fb_available, sizeof(fb_available), available),
-                                         format_bytes(fb_need, sizeof(fb_need), RELOAD_DISK_SPACE_MIN));
-        }
+                                         FORMAT_BYTES(available),
+                                         FORMAT_BYTES(RELOAD_DISK_SPACE_MIN));
 
         return 0;
 }
@@ -1530,13 +1528,11 @@ static int method_switch_root(sd_bus_message *message, void *userdata, sd_bus_er
 
         available = (uint64_t) svfs.f_bfree * (uint64_t) svfs.f_bsize;
 
-        if (available < RELOAD_DISK_SPACE_MIN) {
-                char fb_available[FORMAT_BYTES_MAX], fb_need[FORMAT_BYTES_MAX];
+        if (available < RELOAD_DISK_SPACE_MIN)
                 log_warning("Dangerously low amount of free space on /run/systemd, root switching might fail.\n"
                             "Currently, %s are free, but %s are suggested. Proceeding anyway.",
-                            format_bytes(fb_available, sizeof(fb_available), available),
-                            format_bytes(fb_need, sizeof(fb_need), RELOAD_DISK_SPACE_MIN));
-        }
+                            FORMAT_BYTES(available),
+                            FORMAT_BYTES(RELOAD_DISK_SPACE_MIN));
 
         r = mac_selinux_access_check(message, "reboot", error);
         if (r < 0)
index f45a5c16eb4ee6de31a9ac3381909c0e7c4cb1bb..a3b1e0442f4f3c16149923aa883bebffb8b9202c 100644 (file)
@@ -65,7 +65,7 @@ static int property_get_listen(
                                 break;
 
                         default:
-                                assert_not_reached("Unknown socket type");
+                                assert_not_reached();
                 }
 
                 r = sd_bus_message_append(reply, "(ss)", socket_port_type_to_string(p), a);
index e54c473d1101c2a16f572dd3596534b8266fa273..9d823279dd353a596fd83802de7ae60b77c726a5 100644 (file)
@@ -147,13 +147,12 @@ static int timer_add_one_monotonic_spec(
                 sd_bus_error *error) {
 
         if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
-                char ts[FORMAT_TIMESPAN_MAX];
                 TimerValue *v;
 
                 unit_write_settingf(UNIT(t), flags|UNIT_ESCAPE_SPECIFIERS, name,
                                     "%s=%s",
                                     timer_base_to_string(base),
-                                    format_timespan(ts, sizeof ts, usec, USEC_PER_MSEC));
+                                    FORMAT_TIMESPAN(usec, USEC_PER_MSEC));
 
                 v = new(TimerValue, 1);
                 if (!v)
index ca9b399d8c91b0de1d8b6c8ee26f560d8baeb34a..f0e75d5bc279af1107a7b7199f9e9a1f8e6f0fe6 100644 (file)
@@ -112,16 +112,13 @@ int bus_set_transient_usec_internal(
                 return r;
 
         if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
-                char *n, ts[FORMAT_TIMESPAN_MAX];
-
                 if (fix_0)
                         *p = v != 0 ? v: USEC_INFINITY;
                 else
                         *p = v;
 
-                n = strndupa(name, strlen(name) - 4);
-                unit_write_settingf(u, flags, name, "%sSec=%s", n,
-                                    format_timespan(ts, sizeof(ts), v, USEC_PER_MSEC));
+                char *n = strndupa(name, strlen(name) - 4);
+                unit_write_settingf(u, flags, name, "%sSec=%s", n, FORMAT_TIMESPAN(v, USEC_PER_MSEC));
         }
 
         return 1;
index 7da87fd818bb4ce0c79202e0e29e4c4d5b0da32c..2672496724c72e2012ed7b12b4b7f383839e2e16 100644 (file)
@@ -253,7 +253,7 @@ static int pick_uid(char **suggested_paths, const char *name, uid_t *ret_uid) {
                         break;
 
                 default:
-                        assert_not_reached("unknown phase");
+                        assert_not_reached();
                 }
 
                 /* Make sure whatever we picked here actually is in the right range */
index 9e8c79e67a6b4702bb5430040a25352640576274..0234772b95326f0e9e35e94ff6dc3b3088830ca2 100644 (file)
@@ -146,7 +146,7 @@ void emergency_action(
                 break;
 
         default:
-                assert_not_reached("Unknown emergency action");
+                assert_not_reached();
         }
 }
 
index f760d6ae07aefbad8adf2b70e588fdfc447be7a5..460895625904ce98247d8456701cfa522c48f047 100644 (file)
@@ -52,6 +52,7 @@
 #include "env-file.h"
 #include "env-util.h"
 #include "errno-list.h"
+#include "escape.h"
 #include "execute.h"
 #include "exit-status.h"
 #include "fd-util.h"
@@ -543,7 +544,7 @@ static int setup_input(
         }
 
         default:
-                assert_not_reached("Unknown input type");
+                assert_not_reached();
         }
 }
 
@@ -729,7 +730,7 @@ static int setup_output(
         }
 
         default:
-                assert_not_reached("Unknown error type");
+                assert_not_reached();
         }
 }
 
@@ -922,7 +923,7 @@ static int ask_for_confirmation(const char *vc, Unit *u, const char *cmdline) {
                         r = CONFIRM_EXECUTE;
                         break;
                 default:
-                        assert_not_reached("Unhandled choice");
+                        assert_not_reached();
                 }
                 break;
         }
@@ -3638,8 +3639,6 @@ static int compile_suggested_paths(const ExecContext *c, const ExecParameters *p
         return 0;
 }
 
-static char *exec_command_line(char **argv);
-
 static int exec_parameters_get_cgroup_path(const ExecParameters *params, char **ret) {
         bool using_subcgroup;
         char *p;
@@ -3842,7 +3841,7 @@ static int exec_child(
                 const char *vc = params->confirm_spawn;
                 _cleanup_free_ char *cmdline = NULL;
 
-                cmdline = exec_command_line(command->argv);
+                cmdline = quote_command_line(command->argv);
                 if (!cmdline) {
                         *exit_status = EXIT_MEMORY;
                         return log_oom();
@@ -4688,12 +4687,15 @@ static int exec_child(
         if (DEBUG_LOGGING) {
                 _cleanup_free_ char *line = NULL;
 
-                line = exec_command_line(final_argv);
-                if (line)
-                        log_unit_struct(unit, LOG_DEBUG,
-                                        "EXECUTABLE=%s", executable,
-                                        LOG_UNIT_MESSAGE(unit, "Executing: %s", line),
-                                        LOG_UNIT_INVOCATION_ID(unit));
+                line = quote_command_line(final_argv);
+                if (!line) {
+                        *exit_status = EXIT_MEMORY;
+                        return log_oom();
+                }
+
+                log_unit_struct(unit, LOG_DEBUG,
+                                "EXECUTABLE=%s", executable,
+                                LOG_UNIT_MESSAGE(unit, "Executing: %s", line));
         }
 
         if (exec_fd >= 0) {
@@ -4777,7 +4779,7 @@ int exec_spawn(Unit *unit,
         if (r < 0)
                 return log_unit_error_errno(unit, r, "Failed to load environment files: %m");
 
-        line = exec_command_line(command->argv);
+        line = quote_command_line(command->argv);
         if (!line)
                 return log_oom();
 
@@ -5286,7 +5288,7 @@ static void strv_dump(FILE* f, const char *prefix, const char *name, char **strv
 }
 
 void exec_context_dump(const ExecContext *c, FILE* f, const char *prefix) {
-        char **e, **d, buf_clean[FORMAT_TIMESPAN_MAX];
+        char **e, **d;
         int r;
 
         assert(c);
@@ -5404,24 +5406,16 @@ void exec_context_dump(const ExecContext *c, FILE* f, const char *prefix) {
                         fprintf(f, "%s%s: %s\n", prefix, exec_directory_type_to_string(dt), *d);
         }
 
-        fprintf(f,
-                "%sTimeoutCleanSec: %s\n",
-                prefix, format_timespan(buf_clean, sizeof(buf_clean), c->timeout_clean_usec, USEC_PER_SEC));
+        fprintf(f, "%sTimeoutCleanSec: %s\n", prefix, FORMAT_TIMESPAN(c->timeout_clean_usec, USEC_PER_SEC));
 
         if (c->nice_set)
-                fprintf(f,
-                        "%sNice: %i\n",
-                        prefix, c->nice);
+                fprintf(f, "%sNice: %i\n", prefix, c->nice);
 
         if (c->oom_score_adjust_set)
-                fprintf(f,
-                        "%sOOMScoreAdjust: %i\n",
-                        prefix, c->oom_score_adjust);
+                fprintf(f, "%sOOMScoreAdjust: %i\n", prefix, c->oom_score_adjust);
 
         if (c->coredump_filter_set)
-                fprintf(f,
-                        "%sCoredumpFilter: 0x%"PRIx64"\n",
-                        prefix, c->coredump_filter);
+                fprintf(f, "%sCoredumpFilter: 0x%"PRIx64"\n", prefix, c->coredump_filter);
 
         for (unsigned i = 0; i < RLIM_NLIMITS; i++)
                 if (c->rlimit[i]) {
@@ -5544,13 +5538,10 @@ void exec_context_dump(const ExecContext *c, FILE* f, const char *prefix) {
                 fprintf(f, "%sLogLevelMax: %s\n", prefix, strna(t));
         }
 
-        if (c->log_ratelimit_interval_usec > 0) {
-                char buf_timespan[FORMAT_TIMESPAN_MAX];
-
+        if (c->log_ratelimit_interval_usec > 0)
                 fprintf(f,
                         "%sLogRateLimitIntervalSec: %s\n",
-                        prefix, format_timespan(buf_timespan, sizeof(buf_timespan), c->log_ratelimit_interval_usec, USEC_PER_SEC));
-        }
+                        prefix, FORMAT_TIMESPAN(c->log_ratelimit_interval_usec, USEC_PER_SEC));
 
         if (c->log_ratelimit_burst > 0)
                 fprintf(f, "%sLogRateLimitBurst: %u\n", prefix, c->log_ratelimit_burst);
@@ -5963,8 +5954,6 @@ void exec_status_reset(ExecStatus *s) {
 }
 
 void exec_status_dump(const ExecStatus *s, FILE *f, const char *prefix) {
-        char buf[FORMAT_TIMESTAMP_MAX];
-
         assert(s);
         assert(f);
 
@@ -5980,58 +5969,18 @@ void exec_status_dump(const ExecStatus *s, FILE *f, const char *prefix) {
         if (dual_timestamp_is_set(&s->start_timestamp))
                 fprintf(f,
                         "%sStart Timestamp: %s\n",
-                        prefix, format_timestamp(buf, sizeof(buf), s->start_timestamp.realtime));
+                        prefix, FORMAT_TIMESTAMP(s->start_timestamp.realtime));
 
         if (dual_timestamp_is_set(&s->exit_timestamp))
                 fprintf(f,
                         "%sExit Timestamp: %s\n"
                         "%sExit Code: %s\n"
                         "%sExit Status: %i\n",
-                        prefix, format_timestamp(buf, sizeof(buf), s->exit_timestamp.realtime),
+                        prefix, FORMAT_TIMESTAMP(s->exit_timestamp.realtime),
                         prefix, sigchld_code_to_string(s->code),
                         prefix, s->status);
 }
 
-static char *exec_command_line(char **argv) {
-        size_t k;
-        char *n, *p, **a;
-        bool first = true;
-
-        assert(argv);
-
-        k = 1;
-        STRV_FOREACH(a, argv)
-                k += strlen(*a)+3;
-
-        n = new(char, k);
-        if (!n)
-                return NULL;
-
-        p = n;
-        STRV_FOREACH(a, argv) {
-
-                if (!first)
-                        *(p++) = ' ';
-                else
-                        first = false;
-
-                if (strpbrk(*a, WHITESPACE)) {
-                        *(p++) = '\'';
-                        p = stpcpy(p, *a);
-                        *(p++) = '\'';
-                } else
-                        p = stpcpy(p, *a);
-
-        }
-
-        *p = 0;
-
-        /* FIXME: this doesn't really handle arguments that have
-         * spaces and ticks in them */
-
-        return n;
-}
-
 static void exec_command_dump(ExecCommand *c, FILE *f, const char *prefix) {
         _cleanup_free_ char *cmd = NULL;
         const char *prefix2;
@@ -6042,7 +5991,7 @@ static void exec_command_dump(ExecCommand *c, FILE *f, const char *prefix) {
         prefix = strempty(prefix);
         prefix2 = strjoina(prefix, "\t");
 
-        cmd = exec_command_line(c->argv);
+        cmd = quote_command_line(c->argv);
         fprintf(f,
                 "%sCommand Line: %s\n",
                 prefix, cmd ? cmd : strerror_safe(ENOMEM));
index eb6728ad879e5401d5ae96da837dfd321297e05d..dd16a0b2804ed1f5e6f1d425fa10a986fab08379 100644 (file)
@@ -407,7 +407,7 @@ bool job_type_is_redundant(JobType a, UnitActiveState b) {
                 return true;
 
         default:
-                assert_not_reached("Invalid job type");
+                assert_not_reached();
         }
 }
 
@@ -781,7 +781,7 @@ static int job_perform_on_unit(Job **j) {
                         break;
 
                 default:
-                        assert_not_reached("Invalid job type");
+                        assert_not_reached();
         }
 
         /* Log if the job still exists and the start/stop/reload function actually did something. Note that this means
@@ -849,7 +849,7 @@ int job_run_and_invalidate(Job *j) {
                         break;
 
                 default:
-                        assert_not_reached("Unknown job type");
+                        assert_not_reached();
         }
 
         if (j) {
@@ -1511,44 +1511,44 @@ static const char* const job_state_table[_JOB_STATE_MAX] = {
 DEFINE_STRING_TABLE_LOOKUP(job_state, JobState);
 
 static const char* const job_type_table[_JOB_TYPE_MAX] = {
-        [JOB_START] = "start",
-        [JOB_VERIFY_ACTIVE] = "verify-active",
-        [JOB_STOP] = "stop",
-        [JOB_RELOAD] = "reload",
+        [JOB_START]           = "start",
+        [JOB_VERIFY_ACTIVE]   = "verify-active",
+        [JOB_STOP]            = "stop",
+        [JOB_RELOAD]          = "reload",
         [JOB_RELOAD_OR_START] = "reload-or-start",
-        [JOB_RESTART] = "restart",
-        [JOB_TRY_RESTART] = "try-restart",
-        [JOB_TRY_RELOAD] = "try-reload",
-        [JOB_NOP] = "nop",
+        [JOB_RESTART]         = "restart",
+        [JOB_TRY_RESTART]     = "try-restart",
+        [JOB_TRY_RELOAD]      = "try-reload",
+        [JOB_NOP]             = "nop",
 };
 
 DEFINE_STRING_TABLE_LOOKUP(job_type, JobType);
 
 static const char* const job_mode_table[_JOB_MODE_MAX] = {
-        [JOB_FAIL] = "fail",
-        [JOB_REPLACE] = "replace",
+        [JOB_FAIL]                 = "fail",
+        [JOB_REPLACE]              = "replace",
         [JOB_REPLACE_IRREVERSIBLY] = "replace-irreversibly",
-        [JOB_ISOLATE] = "isolate",
-        [JOB_FLUSH] = "flush",
-        [JOB_IGNORE_DEPENDENCIES] = "ignore-dependencies",
-        [JOB_IGNORE_REQUIREMENTS] = "ignore-requirements",
-        [JOB_TRIGGERING] = "triggering",
+        [JOB_ISOLATE]              = "isolate",
+        [JOB_FLUSH]                = "flush",
+        [JOB_IGNORE_DEPENDENCIES]  = "ignore-dependencies",
+        [JOB_IGNORE_REQUIREMENTS]  = "ignore-requirements",
+        [JOB_TRIGGERING]           = "triggering",
 };
 
 DEFINE_STRING_TABLE_LOOKUP(job_mode, JobMode);
 
 static const char* const job_result_table[_JOB_RESULT_MAX] = {
-        [JOB_DONE] = "done",
-        [JOB_CANCELED] = "canceled",
-        [JOB_TIMEOUT] = "timeout",
-        [JOB_FAILED] = "failed",
-        [JOB_DEPENDENCY] = "dependency",
-        [JOB_SKIPPED] = "skipped",
-        [JOB_INVALID] = "invalid",
-        [JOB_ASSERT] = "assert",
+        [JOB_DONE]        = "done",
+        [JOB_CANCELED]    = "canceled",
+        [JOB_TIMEOUT]     = "timeout",
+        [JOB_FAILED]      = "failed",
+        [JOB_DEPENDENCY]  = "dependency",
+        [JOB_SKIPPED]     = "skipped",
+        [JOB_INVALID]     = "invalid",
+        [JOB_ASSERT]      = "assert",
         [JOB_UNSUPPORTED] = "unsupported",
-        [JOB_COLLECTED] = "collected",
-        [JOB_ONCE] = "once",
+        [JOB_COLLECTED]   = "collected",
+        [JOB_ONCE]        = "once",
 };
 
 DEFINE_STRING_TABLE_LOOKUP(job_result, JobResult);
index c72f5c22da79a48093fd7ed5611dd502c5bb2f1c..6eefaaf27d7700c28de9f2be5f4cf34419ee9077 100644 (file)
@@ -1010,8 +1010,6 @@ int config_parse_exec_input_text(
         _cleanup_free_ char *unescaped = NULL, *resolved = NULL;
         ExecContext *c = data;
         const Unit *u = userdata;
-        size_t sz;
-        void *p;
         int r;
 
         assert(data);
@@ -1026,9 +1024,9 @@ int config_parse_exec_input_text(
                 return 0;
         }
 
-        r = cunescape(rvalue, 0, &unescaped);
-        if (r < 0) {
-                log_syntax(unit, LOG_WARNING, filename, line, r,
+        ssize_t l = cunescape(rvalue, 0, &unescaped);
+        if (l < 0) {
+                log_syntax(unit, LOG_WARNING, filename, line, l,
                            "Failed to decode C escaped text '%s', ignoring: %m", rvalue);
                 return 0;
         }
@@ -1040,7 +1038,7 @@ int config_parse_exec_input_text(
                 return 0;
         }
 
-        sz = strlen(resolved);
+        size_t sz = strlen(resolved);
         if (c->stdin_data_size + sz + 1 < c->stdin_data_size || /* check for overflow */
             c->stdin_data_size + sz + 1 > EXEC_STDIN_DATA_MAX) {
                 log_syntax(unit, LOG_WARNING, filename, line, 0,
@@ -1049,7 +1047,7 @@ int config_parse_exec_input_text(
                 return 0;
         }
 
-        p = realloc(c->stdin_data, c->stdin_data_size + sz + 1);
+        void *p = realloc(c->stdin_data, c->stdin_data_size + sz + 1);
         if (!p)
                 return log_oom();
 
@@ -4515,8 +4513,8 @@ int config_parse_set_credential(
                         return 0;
                 }
         } else {
-                char *unescaped = NULL;
-                int l;
+                char *unescaped;
+                ssize_t l;
 
                 /* We support escape codes here, so that users can insert trailing \n if they like */
                 l = cunescape(p, UNESCAPE_ACCEPT_NUL, &unescaped);
index da6c50a1c40e10933f555f68f8f1bfb1b71f5928..eb24245fb353281ae6e7f6f400e237f6de76c010 100644 (file)
@@ -55,6 +55,7 @@
 #include "machine-id-setup.h"
 #include "manager.h"
 #include "manager-dump.h"
+#include "manager-serialize.h"
 #include "mkdir.h"
 #include "mount-setup.h"
 #include "os-util.h"
@@ -82,6 +83,7 @@
 #include "switch-root.h"
 #include "sysctl-util.h"
 #include "terminal-util.h"
+#include "time-util.h"
 #include "umask-util.h"
 #include "user-util.h"
 #include "util.h"
@@ -256,7 +258,7 @@ _noreturn_ static void crash(int sig) {
                         pid = raw_getpid();
                         (void) kill(pid, sig); /* raise() would kill the parent */
 
-                        assert_not_reached("We shouldn't be here...");
+                        assert_not_reached();
                         _exit(EXIT_EXCEPTION);
                 } else {
                         siginfo_t status;
@@ -1079,7 +1081,7 @@ static int parse_argv(int argc, char *argv[]) {
                                 return 0;
 
                 default:
-                        assert_not_reached("Unhandled option code.");
+                        assert_not_reached();
                 }
 
         if (optind < argc && getpid_cached() != 1)
@@ -1188,11 +1190,11 @@ static int prepare_reexecute(
 
 static void bump_file_max_and_nr_open(void) {
 
-        /* Let's bump fs.file-max and fs.nr_open to their respective maximums. On current kernels large numbers of file
-         * descriptors are no longer a performance problem and their memory is properly tracked by memcg, thus counting
-         * them and limiting them in another two layers of limits is unnecessary and just complicates things. This
-         * function hence turns off 2 of the 4 levels of limits on file descriptors, and makes RLIMIT_NOLIMIT (soft +
-         * hard) the only ones that really matter. */
+        /* Let's bump fs.file-max and fs.nr_open to their respective maximums. On current kernels large
+         * numbers of file descriptors are no longer a performance problem and their memory is properly
+         * tracked by memcg, thus counting them and limiting them in another two layers of limits is
+         * unnecessary and just complicates things. This function hence turns off 2 of the 4 levels of limits
+         * on file descriptors, and makes RLIMIT_NOLIMIT (soft + hard) the only ones that really matter. */
 
 #if BUMP_PROC_SYS_FS_FILE_MAX || BUMP_PROC_SYS_FS_NR_OPEN
         int r;
@@ -1209,12 +1211,12 @@ static void bump_file_max_and_nr_open(void) {
 #if BUMP_PROC_SYS_FS_NR_OPEN
         int v = INT_MAX;
 
-        /* Arg! The kernel enforces maximum and minimum values on the fs.nr_open, but we don't really know what they
-         * are. The expression by which the maximum is determined is dependent on the architecture, and is something we
-         * don't really want to copy to userspace, as it is dependent on implementation details of the kernel. Since
-         * the kernel doesn't expose the maximum value to us, we can only try and hope. Hence, let's start with
-         * INT_MAX, and then keep halving the value until we find one that works. Ugly? Yes, absolutely, but kernel
-         * APIs are kernel APIs, so what do can we do... 🤯 */
+        /* Argh! The kernel enforces maximum and minimum values on the fs.nr_open, but we don't really know
+         * what they are. The expression by which the maximum is determined is dependent on the architecture,
+         * and is something we don't really want to copy to userspace, as it is dependent on implementation
+         * details of the kernel. Since the kernel doesn't expose the maximum value to us, we can only try
+         * and hope. Hence, let's start with INT_MAX, and then keep halving the value until we find one that
+         * works. Ugly? Yes, absolutely, but kernel APIs are kernel APIs, so what do can we do... 🤯 */
 
         for (;;) {
                 int k;
@@ -1286,16 +1288,17 @@ static int bump_rlimit_memlock(struct rlimit *saved_rlimit) {
         uint64_t mm;
         int r;
 
-        /* BPF_MAP_TYPE_LPM_TRIE bpf maps are charged against RLIMIT_MEMLOCK, even if we have CAP_IPC_LOCK which should
-         * normally disable such checks. We need them to implement IPAddressAllow= and IPAddressDeny=, hence let's bump
-         * the value high enough for our user. */
+        /* BPF_MAP_TYPE_LPM_TRIE bpf maps are charged against RLIMIT_MEMLOCK, even if we have CAP_IPC_LOCK
+         * which should normally disable such checks. We need them to implement IPAddressAllow= and
+         * IPAddressDeny=, hence let's bump the value high enough for our user. */
 
         /* Using MAX() on resource limits only is safe if RLIM_INFINITY is > 0. POSIX declares that rlim_t
          * must be unsigned, hence this is a given, but let's make this clear here. */
         assert_cc(RLIM_INFINITY > 0);
 
-        mm = physical_memory_scale(1, 8); /* Let's scale how much we allow to be locked by the amount of physical
-                                           * RAM. We allow an eighth to be locked by us, just to pick a value. */
+        mm = physical_memory_scale(1, 8); /* Let's scale how much we allow to be locked by the amount of
+                                           * physical RAM. We allow an eighth to be locked by us, just to
+                                           * pick a value. */
 
         new_rlimit = (struct rlimit) {
                 .rlim_cur = MAX3(HIGH_RLIMIT_MEMLOCK, saved_rlimit->rlim_cur, mm),
@@ -1387,13 +1390,14 @@ static int bump_unix_max_dgram_qlen(void) {
         unsigned long v;
         int r;
 
-        /* Let's bump the net.unix.max_dgram_qlen sysctl. The kernel default of 16 is simply too low. We set the value
-         * really really early during boot, so that it is actually applied to all our sockets, including the
-         * $NOTIFY_SOCKET one. */
+        /* Let's bump the net.unix.max_dgram_qlen sysctl. The kernel default of 16 is simply too low. We set
+         * the value really really early during boot, so that it is actually applied to all our sockets,
+         * including the $NOTIFY_SOCKET one. */
 
         r = read_one_line_file("/proc/sys/net/unix/max_dgram_qlen", &qlen);
         if (r < 0)
-                return log_full_errno(r == -ENOENT ? LOG_DEBUG : LOG_WARNING, r, "Failed to read AF_UNIX datagram queue length, ignoring: %m");
+                return log_full_errno(r == -ENOENT ? LOG_DEBUG : LOG_WARNING, r,
+                                      "Failed to read AF_UNIX datagram queue length, ignoring: %m");
 
         r = safe_atolu(qlen, &v);
         if (r < 0)
@@ -1402,7 +1406,8 @@ static int bump_unix_max_dgram_qlen(void) {
         if (v >= DEFAULT_UNIX_MAX_DGRAM_QLEN)
                 return 0;
 
-        r = write_string_filef("/proc/sys/net/unix/max_dgram_qlen", WRITE_STRING_FILE_DISABLE_BUFFER, "%lu", DEFAULT_UNIX_MAX_DGRAM_QLEN);
+        r = write_string_filef("/proc/sys/net/unix/max_dgram_qlen", WRITE_STRING_FILE_DISABLE_BUFFER,
+                               "%lu", DEFAULT_UNIX_MAX_DGRAM_QLEN);
         if (r < 0)
                 return log_full_errno(IN_SET(r, -EROFS, -EPERM, -EACCES) ? LOG_DEBUG : LOG_WARNING, r,
                                       "Failed to bump AF_UNIX datagram queue length, ignoring: %m");
@@ -1423,9 +1428,9 @@ static int fixup_environment(void) {
         if (detect_container() > 0)
                 return 0;
 
-        /* When started as PID1, the kernel uses /dev/console for our stdios and uses TERM=linux whatever the backend
-         * device used by the console. We try to make a better guess here since some consoles might not have support
-         * for color mode for example.
+        /* When started as PID1, the kernel uses /dev/console for our stdios and uses TERM=linux whatever the
+         * backend device used by the console. We try to make a better guess here since some consoles might
+         * not have support for color mode for example.
          *
          * However if TERM was configured through the kernel command line then leave it alone. */
         r = proc_cmdline_get_key("TERM", 0, &term);
@@ -1568,12 +1573,11 @@ static void initialize_clock(void) {
         if (clock_is_localtime(NULL) > 0) {
                 int min;
 
-                /*
-                 * The very first call of settimeofday() also does a time warp in the kernel.
+                /* The very first call of settimeofday() also does a time warp in the kernel.
                  *
-                 * In the rtc-in-local time mode, we set the kernel's timezone, and rely on external tools to take care
-                 * of maintaining the RTC and do all adjustments.  This matches the behavior of Windows, which leaves
-                 * the RTC alone if the registry tells that the RTC runs in UTC.
+                 * In the rtc-in-local time mode, we set the kernel's timezone, and rely on external tools to
+                 * take care of maintaining the RTC and do all adjustments.  This matches the behavior of
+                 * Windows, which leaves the RTC alone if the registry tells that the RTC runs in UTC.
                  */
                 r = clock_set_timezone(&min);
                 if (r < 0)
@@ -1585,21 +1589,28 @@ static void initialize_clock(void) {
                 /*
                  * Do a dummy very first call to seal the kernel's time warp magic.
                  *
-                 * Do not call this from inside the initrd. The initrd might not carry /etc/adjtime with LOCAL, but the
-                 * real system could be set up that way. In such case, we need to delay the time-warp or the sealing
-                 * until we reach the real system.
+                 * Do not call this from inside the initrd. The initrd might not carry /etc/adjtime with
+                 * LOCAL, but the real system could be set up that way. In such case, we need to delay the
+                 * time-warp or the sealing until we reach the real system.
                  *
-                 * Do no set the kernel's timezone. The concept of local time cannot be supported reliably, the time
-                 * will jump or be incorrect at every daylight saving time change. All kernel local time concepts will
-                 * be treated as UTC that way.
+                 * Do no set the kernel's timezone. The concept of local time cannot be supported reliably,
+                 * the time will jump or be incorrect at every daylight saving time change. All kernel local
+                 * time concepts will be treated as UTC that way.
                  */
                 (void) clock_reset_timewarp();
 
-        r = clock_apply_epoch();
-        if (r < 0)
-                log_error_errno(r, "Current system time is before build time, but cannot correct: %m");
-        else if (r > 0)
+        ClockChangeDirection change_dir;
+        r = clock_apply_epoch(&change_dir);
+        if (r > 0 && change_dir == CLOCK_CHANGE_FORWARD)
                 log_info("System time before build time, advancing clock.");
+        else if (r > 0 && change_dir == CLOCK_CHANGE_BACKWARD)
+                log_info("System time is further ahead than %s after build time, resetting clock to build time.",
+                         FORMAT_TIMESPAN(CLOCK_VALID_RANGE_USEC_MAX, USEC_PER_DAY));
+        else if (r < 0 && change_dir == CLOCK_CHANGE_FORWARD)
+                log_error_errno(r, "Current system time is before build time, but cannot correct: %m");
+        else if (r < 0 && change_dir == CLOCK_CHANGE_BACKWARD)
+                log_error_errno(r, "Current system time is further ahead %s after build time, but cannot correct: %m",
+                                FORMAT_TIMESPAN(CLOCK_VALID_RANGE_USEC_MAX, USEC_PER_DAY));
 }
 
 static void apply_clock_update(void) {
@@ -1616,12 +1627,9 @@ static void apply_clock_update(void) {
 
         if (clock_settime(CLOCK_REALTIME, timespec_store(&ts, arg_clock_usec)) < 0)
                 log_error_errno(errno, "Failed to set system clock to time specified on kernel command line: %m");
-        else {
-                char buf[FORMAT_TIMESTAMP_MAX];
-
+        else
                 log_info("Set system clock to %s, as specified on the kernel command line.",
-                         format_timestamp(buf, sizeof(buf), arg_clock_usec));
-        }
+                         FORMAT_TIMESTAMP(arg_clock_usec));
 }
 
 static void cmdline_take_random_seed(void) {
@@ -1648,7 +1656,8 @@ static void cmdline_take_random_seed(void) {
         }
 
         log_notice("Successfully credited entropy passed on kernel command line.\n"
-                   "Note that the seed provided this way is accessible to unprivileged programs. This functionality should not be used outside of testing environments.");
+                   "Note that the seed provided this way is accessible to unprivileged programs. "
+                   "This functionality should not be used outside of testing environments.");
 }
 
 static void initialize_coredump(bool skip_setup) {
@@ -1656,15 +1665,14 @@ static void initialize_coredump(bool skip_setup) {
         if (getpid_cached() != 1)
                 return;
 
-        /* Don't limit the core dump size, so that coredump handlers such as systemd-coredump (which honour the limit)
-         * will process core dumps for system services by default. */
+        /* Don't limit the core dump size, so that coredump handlers such as systemd-coredump (which honour
+         * the limit) will process core dumps for system services by default. */
         if (setrlimit(RLIMIT_CORE, &RLIMIT_MAKE_CONST(RLIM_INFINITY)) < 0)
                 log_warning_errno(errno, "Failed to set RLIMIT_CORE: %m");
 
-        /* But at the same time, turn off the core_pattern logic by default, so that no
-         * coredumps are stored until the systemd-coredump tool is enabled via
-         * sysctl. However it can be changed via the kernel command line later so core
-         * dumps can still be generated during early startup and in initramfs. */
+        /* But at the same time, turn off the core_pattern logic by default, so that no coredumps are stored
+         * until the systemd-coredump tool is enabled via sysctl. However it can be changed via the kernel
+         * command line later so core dumps can still be generated during early startup and in initramfs. */
         if (!skip_setup)
                 disable_coredumps();
 #endif
@@ -1681,7 +1689,8 @@ static void initialize_core_pattern(bool skip_setup) {
 
         r = write_string_file("/proc/sys/kernel/core_pattern", arg_early_core_pattern, WRITE_STRING_FILE_DISABLE_BUFFER);
         if (r < 0)
-                log_warning_errno(r, "Failed to write '%s' to /proc/sys/kernel/core_pattern, ignoring: %m", arg_early_core_pattern);
+                log_warning_errno(r, "Failed to write '%s' to /proc/sys/kernel/core_pattern, ignoring: %m",
+                                  arg_early_core_pattern);
 }
 
 static void update_cpu_affinity(bool skip_setup) {
@@ -1720,9 +1729,54 @@ static void update_numa_policy(bool skip_setup) {
                 log_warning_errno(r, "Failed to set NUMA memory policy: %m");
 }
 
+static void filter_args(
+                const char* dst[],
+                size_t *dst_index,
+                char **src,
+                int argc) {
+
+        assert(dst);
+        assert(dst_index);
+
+        /* Copy some filtered arguments into the dst array from src. */
+        for (int i = 1; i < argc; i++) {
+                if (STR_IN_SET(src[i],
+                               "--switched-root",
+                               "--system",
+                               "--user"))
+                        continue;
+
+                if (startswith(src[i], "--deserialize="))
+                        continue;
+                if (streq(src[i], "--deserialize")) {
+                        i++;                            /* Skip the argument too */
+                        continue;
+                }
+
+                /* Skip target unit designators. We already acted upon this information and have queued
+                 * appropriate jobs. We don't want to redo all this after reexecution. */
+                if (startswith(src[i], "--unit="))
+                        continue;
+                if (streq(src[i], "--unit")) {
+                        i++;                            /* Skip the argument too */
+                        continue;
+                }
+
+                if (startswith(src[i],
+                               in_initrd() ? "rd.systemd.unit=" : "systemd.unit="))
+                        continue;
+
+                if (runlevel_to_target(src[i]))
+                        continue;
+
+                /* Seems we have a good old option. Let's pass it over to the new instance. */
+                dst[(*dst_index)++] = src[i];
+        }
+}
+
 static void do_reexecute(
                 int argc,
-                char *argv[],
+                charargv[],
                 const struct rlimit *saved_rlimit_nofile,
                 const struct rlimit *saved_rlimit_memlock,
                 FDSet *fds,
@@ -1730,16 +1784,17 @@ static void do_reexecute(
                 const char *switch_root_init,
                 const char **ret_error_message) {
 
-        unsigned i, j, args_size;
+        size_t i, args_size;
         const char **args;
         int r;
 
+        assert(argc >= 0);
         assert(saved_rlimit_nofile);
         assert(saved_rlimit_memlock);
         assert(ret_error_message);
 
-        /* Close and disarm the watchdog, so that the new instance can reinitialize it, but doesn't get rebooted while
-         * we do that */
+        /* Close and disarm the watchdog, so that the new instance can reinitialize it, but doesn't get
+         * rebooted while we do that */
         watchdog_close(true);
 
         /* Reset RLIMIT_NOFILE + RLIMIT_MEMLOCK back to the kernel defaults, so that the new systemd can pass
@@ -1750,8 +1805,8 @@ static void do_reexecute(
                 (void) setrlimit(RLIMIT_MEMLOCK, saved_rlimit_memlock);
 
         if (switch_root_dir) {
-                /* Kill all remaining processes from the initrd, but don't wait for them, so that we can handle the
-                 * SIGCHLD for them after deserializing. */
+                /* Kill all remaining processes from the initrd, but don't wait for them, so that we can
+                 * handle the SIGCHLD for them after deserializing. */
                 broadcast_signal(SIGTERM, false, true, arg_default_timeout_stop_usec);
 
                 /* And switch root with MS_MOVE, because we remove the old directory afterwards and detach it. */
@@ -1760,22 +1815,23 @@ static void do_reexecute(
                         log_error_errno(r, "Failed to switch root, trying to continue: %m");
         }
 
-        args_size = MAX(6, argc+1);
+        args_size = argc + 6;
         args = newa(const char*, args_size);
 
         if (!switch_root_init) {
-                char sfd[DECIMAL_STR_MAX(int) + 1];
+                char sfd[DECIMAL_STR_MAX(int)];
 
-                /* First try to spawn ourselves with the right path, and with full serialization. We do this only if
-                 * the user didn't specify an explicit init to spawn. */
+                /* First try to spawn ourselves with the right path, and with full serialization. We do this
+                 * only if the user didn't specify an explicit init to spawn. */
 
                 assert(arg_serialization);
                 assert(fds);
 
                 xsprintf(sfd, "%i", fileno(arg_serialization));
 
-                i = 0;
-                args[i++] = SYSTEMD_BINARY_PATH;
+                i = 1;         /* Leave args[0] empty for now. */
+                filter_args(args, &i, argv, argc);
+
                 if (switch_root_dir)
                         args[i++] = "--switched-root";
                 args[i++] = arg_system ? "--system" : "--user";
@@ -1786,20 +1842,21 @@ static void do_reexecute(
                 assert(i <= args_size);
 
                 /*
-                 * We want valgrind to print its memory usage summary before reexecution.  Valgrind won't do this is on
-                 * its own on exec(), but it will do it on exit().  Hence, to ensure we get a summary here, fork() off
-                 * a child, let it exit() cleanly, so that it prints the summary, and wait() for it in the parent,
-                 * before proceeding into the exec().
+                 * We want valgrind to print its memory usage summary before reexecution.  Valgrind won't do
+                 * this is on its own on exec(), but it will do it on exit().  Hence, to ensure we get a
+                 * summary here, fork() off a child, let it exit() cleanly, so that it prints the summary,
+                 * and wait() for it in the parent, before proceeding into the exec().
                  */
                 valgrind_summary_hack();
 
+                args[0] = SYSTEMD_BINARY_PATH;
                 (void) execv(args[0], (char* const*) args);
-                log_debug_errno(errno, "Failed to execute our own binary, trying fallback: %m");
+                log_debug_errno(errno, "Failed to execute our own binary %s, trying fallback: %m", args[0]);
         }
 
-        /* Try the fallback, if there is any, without any serialization. We pass the original argv[] and envp[]. (Well,
-         * modulo the ordering changes due to getopt() in argv[], and some cleanups in envp[], but let's hope that
-         * doesn't matter.) */
+        /* Try the fallback, if there is any, without any serialization. We pass the original argv[] and
+         * envp[]. (Well, modulo the ordering changes due to getopt() in argv[], and some cleanups in envp[],
+         * but let's hope that doesn't matter.) */
 
         arg_serialization = safe_fclose(arg_serialization);
         fds = fdset_free(fds);
@@ -1807,9 +1864,9 @@ static void do_reexecute(
         /* Reopen the console */
         (void) make_console_stdio();
 
-        for (j = 1, i = 1; j < (unsigned) argc; j++)
+        i = 1;         /* Leave args[0] empty for now. */
+        for (int j = 1; j <= argc; j++)
                 args[i++] = argv[j];
-        args[i++] = NULL;
         assert(i <= args_size);
 
         /* Re-enable any blocked signals, especially important if we switch from initial ramdisk to init=... */
@@ -1820,7 +1877,7 @@ static void do_reexecute(
         if (switch_root_init) {
                 args[0] = switch_root_init;
                 (void) execve(args[0], (char* const*) args, saved_env);
-                log_warning_errno(errno, "Failed to execute configured init, trying fallback: %m");
+                log_warning_errno(errno, "Failed to execute configured init %s, trying fallback: %m", args[0]);
         }
 
         args[0] = "/sbin/init";
@@ -1884,8 +1941,8 @@ static int invoke_main_loop(
 
                         log_info("Reloading.");
 
-                        /* First, save any overridden log level/target, then parse the configuration file, which might
-                         * change the log level to new settings. */
+                        /* First, save any overridden log level/target, then parse the configuration file,
+                         * which might change the log level to new settings. */
 
                         saved_log_level = m->log_level_overridden ? log_get_max_level() : -1;
                         saved_log_target = m->log_target_overridden ? log_get_target() : _LOG_TARGET_INVALID;
@@ -1905,7 +1962,8 @@ static int invoke_main_loop(
 
                         r = manager_reload(m);
                         if (r < 0)
-                                /* Reloading failed before the point of no return. Let's continue running as if nothing happened. */
+                                /* Reloading failed before the point of no return.
+                                 * Let's continue running as if nothing happened. */
                                 m->objective = MANAGER_OK;
 
                         break;
@@ -1989,7 +2047,7 @@ static int invoke_main_loop(
                 }
 
                 default:
-                        assert_not_reached("Unknown or unexpected manager objective.");
+                        assert_not_reached();
                 }
         }
 }
@@ -2529,8 +2587,8 @@ static void setup_console_terminal(bool skip_setup) {
         /* Become a session leader if we aren't one yet. */
         (void) setsid();
 
-        /* If we are init, we connect stdin/stdout/stderr to /dev/null and make sure we don't have a controlling
-         * tty. */
+        /* If we are init, we connect stdin/stdout/stderr to /dev/null and make sure we don't have a
+         * controlling tty. */
         (void) release_terminal();
 
         /* Reset the console, but only if this is really init and we are freshly booted */
@@ -2541,9 +2599,9 @@ static void setup_console_terminal(bool skip_setup) {
 static bool early_skip_setup_check(int argc, char *argv[]) {
         bool found_deserialize = false;
 
-        /* Determine if this is a reexecution or normal bootup. We do the full command line parsing much later, so
-         * let's just have a quick peek here. Note that if we have switched root, do all the special setup things
-         * anyway, even if in that case we also do deserialization. */
+        /* Determine if this is a reexecution or normal bootup. We do the full command line parsing much
+         * later, so let's just have a quick peek here. Note that if we have switched root, do all the
+         * special setup things anyway, even if in that case we also do deserialization. */
 
         for (int i = 1; i < argc; i++)
                 if (streq(argv[i], "--switched-root"))
@@ -2578,7 +2636,6 @@ int main(int argc, char *argv[]) {
         char *switch_root_dir = NULL, *switch_root_init = NULL;
         usec_t before_startup, after_startup;
         static char systemd[] = "systemd";
-        char timespan[FORMAT_TIMESPAN_MAX];
         const char *shutdown_verb = NULL, *error_message = NULL;
         int r, retval = EXIT_FAILURE;
         Manager *m = NULL;
@@ -2592,11 +2649,12 @@ int main(int argc, char *argv[]) {
         dual_timestamp_get(&userspace_timestamp);
 
         /* Figure out whether we need to do initialize the system, or if we already did that because we are
-         * reexecuting */
+         * reexecuting. */
         skip_setup = early_skip_setup_check(argc, argv);
 
-        /* If we get started via the /sbin/init symlink then we are called 'init'. After a subsequent reexecution we
-         * are then called 'systemd'. That is confusing, hence let's call us systemd right-away. */
+        /* If we get started via the /sbin/init symlink then we are called 'init'. After a subsequent
+         * reexecution we are then called 'systemd'. That is confusing, hence let's call us systemd
+         * right-away. */
         program_invocation_short_name = systemd;
         (void) prctl(PR_SET_NAME, systemd);
 
@@ -2621,14 +2679,14 @@ int main(int argc, char *argv[]) {
                 /* Disable the umask logic */
                 umask(0);
 
-                /* Make sure that at least initially we do not ever log to journald/syslogd, because it might not be
-                 * activated yet (even though the log socket for it exists). */
+                /* Make sure that at least initially we do not ever log to journald/syslogd, because it might
+                 * not be activated yet (even though the log socket for it exists). */
                 log_set_prohibit_ipc(true);
 
-                /* Always reopen /dev/console when running as PID 1 or one of its pre-execve() children. This is
-                 * important so that we never end up logging to any foreign stderr, for example if we have to log in a
-                 * child process right before execve()'ing the actual binary, at a point in time where socket
-                 * activation stderr/stdout area already set up. */
+                /* Always reopen /dev/console when running as PID 1 or one of its pre-execve() children. This
+                 * is important so that we never end up logging to any foreign stderr, for example if we have
+                 * to log in a child process right before execve()'ing the actual binary, at a point in time
+                 * where socket activation stderr/stdout area already set up. */
                 log_set_always_reopen_console(true);
 
                 if (detect_container() <= 0) {
@@ -2671,10 +2729,10 @@ int main(int argc, char *argv[]) {
                         if (!skip_setup)
                                 initialize_clock();
 
-                        /* Set the default for later on, but don't actually open the logs like this for now. Note that
-                         * if we are transitioning from the initrd there might still be journal fd open, and we
-                         * shouldn't attempt opening that before we parsed /proc/cmdline which might redirect output
-                         * elsewhere. */
+                        /* Set the default for later on, but don't actually open the logs like this for
+                         * now. Note that if we are transitioning from the initrd there might still be
+                         * journal fd open, and we shouldn't attempt opening that before we parsed
+                         * /proc/cmdline which might redirect output elsewhere. */
                         log_set_target(LOG_TARGET_JOURNAL_OR_KMSG);
 
                 } else {
@@ -2698,8 +2756,8 @@ int main(int argc, char *argv[]) {
                         goto finish;
                 }
 
-                /* Try to figure out if we can use colors with the console. No need to do that for user instances since
-                 * they never log into the console. */
+                /* Try to figure out if we can use colors with the console. No need to do that for user
+                 * instances since they never log into the console. */
                 log_show_color(colors_enabled());
 
                 r = make_null_stdio();
@@ -2870,7 +2928,7 @@ int main(int argc, char *argv[]) {
 
         log_full(arg_action == ACTION_TEST ? LOG_INFO : LOG_DEBUG,
                  "Loaded units and determined initial transaction in %s.",
-                 format_timespan(timespan, sizeof(timespan), after_startup - before_startup, 100 * USEC_PER_MSEC));
+                 FORMAT_TIMESPAN(after_startup - before_startup, 100 * USEC_PER_MSEC));
 
         if (arg_action == ACTION_TEST) {
                 manager_test_summary(m);
index dba32464e2b9063ae86b66c4fcbd2a6d2ca03b0d..789c552723e7afb481d204e7124cf2b34b61ae88 100644 (file)
@@ -38,14 +38,13 @@ void manager_dump(Manager *m, FILE *f, const char *prefix) {
 
         for (ManagerTimestamp q = 0; q < _MANAGER_TIMESTAMP_MAX; q++) {
                 const dual_timestamp *t = m->timestamps + q;
-                char buf[CONST_MAX(FORMAT_TIMESPAN_MAX, FORMAT_TIMESTAMP_MAX)];
 
                 if (dual_timestamp_is_set(t))
                         fprintf(f, "%sTimestamp %s: %s\n",
                                 strempty(prefix),
                                 manager_timestamp_to_string(q),
-                                timestamp_is_set(t->realtime) ? format_timestamp(buf, sizeof buf, t->realtime) :
-                                                                format_timespan(buf, sizeof buf, t->monotonic, 1));
+                                timestamp_is_set(t->realtime) ? FORMAT_TIMESTAMP(t->realtime) :
+                                                                FORMAT_TIMESPAN(t->monotonic, 1));
         }
 
         manager_dump_units(m, f, prefix);
diff --git a/src/core/manager-serialize.c b/src/core/manager-serialize.c
new file mode 100644 (file)
index 0000000..60a35f4
--- /dev/null
@@ -0,0 +1,536 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+
+#include "clean-ipc.h"
+#include "dbus.h"
+#include "fd-util.h"
+#include "fileio.h"
+#include "format-util.h"
+#include "macro.h"
+#include "manager-serialize.h"
+#include "manager.h"
+#include "parse-util.h"
+#include "serialize.h"
+#include "syslog-util.h"
+#include "unit-serialize.h"
+#include "user-util.h"
+
+int manager_open_serialization(Manager *m, FILE **ret_f) {
+        _cleanup_close_ int fd = -1;
+        FILE *f;
+
+        assert(ret_f);
+
+        fd = open_serialization_fd("systemd-state");
+        if (fd < 0)
+                return fd;
+
+        f = take_fdopen(&fd, "w+");
+        if (!f)
+                return -errno;
+
+        *ret_f = f;
+        return 0;
+}
+
+static bool manager_timestamp_shall_serialize(ManagerTimestamp t) {
+        if (!in_initrd())
+                return true;
+
+        /* The following timestamps only apply to the host system, hence only serialize them there */
+        return !IN_SET(t,
+                       MANAGER_TIMESTAMP_USERSPACE, MANAGER_TIMESTAMP_FINISH,
+                       MANAGER_TIMESTAMP_SECURITY_START, MANAGER_TIMESTAMP_SECURITY_FINISH,
+                       MANAGER_TIMESTAMP_GENERATORS_START, MANAGER_TIMESTAMP_GENERATORS_FINISH,
+                       MANAGER_TIMESTAMP_UNITS_LOAD_START, MANAGER_TIMESTAMP_UNITS_LOAD_FINISH);
+}
+
+static void manager_serialize_uid_refs_internal(
+                FILE *f,
+                Hashmap *uid_refs,
+                const char *field_name) {
+
+        void *p, *k;
+
+        assert(f);
+        assert(field_name);
+
+        /* Serialize the UID reference table. Or actually, just the IPC destruction flag of it, as
+         * the actual counter of it is better rebuild after a reload/reexec. */
+
+        HASHMAP_FOREACH_KEY(p, k, uid_refs) {
+                uint32_t c;
+                uid_t uid;
+
+                uid = PTR_TO_UID(k);
+                c = PTR_TO_UINT32(p);
+
+                if (!(c & DESTROY_IPC_FLAG))
+                        continue;
+
+                (void) serialize_item_format(f, field_name, UID_FMT, uid);
+        }
+}
+
+static void manager_serialize_uid_refs(Manager *m, FILE *f) {
+        manager_serialize_uid_refs_internal(f, m->uid_refs, "destroy-ipc-uid");
+}
+
+static void manager_serialize_gid_refs(Manager *m, FILE *f) {
+        manager_serialize_uid_refs_internal(f, m->gid_refs, "destroy-ipc-gid");
+}
+
+int manager_serialize(
+                Manager *m,
+                FILE *f,
+                FDSet *fds,
+                bool switching_root) {
+
+        const char *t;
+        Unit *u;
+        int r;
+
+        assert(m);
+        assert(f);
+        assert(fds);
+
+        _cleanup_(manager_reloading_stopp) _unused_ Manager *reloading = manager_reloading_start(m);
+
+        (void) serialize_item_format(f, "current-job-id", "%" PRIu32, m->current_job_id);
+        (void) serialize_item_format(f, "n-installed-jobs", "%u", m->n_installed_jobs);
+        (void) serialize_item_format(f, "n-failed-jobs", "%u", m->n_failed_jobs);
+        (void) serialize_bool(f, "taint-usr", m->taint_usr);
+        (void) serialize_bool(f, "ready-sent", m->ready_sent);
+        (void) serialize_bool(f, "taint-logged", m->taint_logged);
+        (void) serialize_bool(f, "service-watchdogs", m->service_watchdogs);
+
+        /* After switching root, udevd has not been started yet. So, enumeration results should not be emitted. */
+        (void) serialize_bool(f, "honor-device-enumeration", !switching_root);
+
+        if (m->show_status_overridden != _SHOW_STATUS_INVALID)
+                (void) serialize_item(f, "show-status-overridden",
+                                      show_status_to_string(m->show_status_overridden));
+
+        if (m->log_level_overridden)
+                (void) serialize_item_format(f, "log-level-override", "%i", log_get_max_level());
+        if (m->log_target_overridden)
+                (void) serialize_item(f, "log-target-override", log_target_to_string(log_get_target()));
+
+        (void) serialize_usec(f, "runtime-watchdog-overridden", m->watchdog_overridden[WATCHDOG_RUNTIME]);
+        (void) serialize_usec(f, "reboot-watchdog-overridden", m->watchdog_overridden[WATCHDOG_REBOOT]);
+        (void) serialize_usec(f, "kexec-watchdog-overridden", m->watchdog_overridden[WATCHDOG_KEXEC]);
+
+        for (ManagerTimestamp q = 0; q < _MANAGER_TIMESTAMP_MAX; q++) {
+                _cleanup_free_ char *joined = NULL;
+
+                if (!manager_timestamp_shall_serialize(q))
+                        continue;
+
+                joined = strjoin(manager_timestamp_to_string(q), "-timestamp");
+                if (!joined)
+                        return log_oom();
+
+                (void) serialize_dual_timestamp(f, joined, m->timestamps + q);
+        }
+
+        if (!switching_root)
+                (void) serialize_strv(f, "env", m->client_environment);
+
+        if (m->notify_fd >= 0) {
+                r = serialize_fd(f, fds, "notify-fd", m->notify_fd);
+                if (r < 0)
+                        return r;
+
+                (void) serialize_item(f, "notify-socket", m->notify_socket);
+        }
+
+        if (m->cgroups_agent_fd >= 0) {
+                r = serialize_fd(f, fds, "cgroups-agent-fd", m->cgroups_agent_fd);
+                if (r < 0)
+                        return r;
+        }
+
+        if (m->user_lookup_fds[0] >= 0) {
+                int copy0, copy1;
+
+                copy0 = fdset_put_dup(fds, m->user_lookup_fds[0]);
+                if (copy0 < 0)
+                        return log_error_errno(copy0, "Failed to add user lookup fd to serialization: %m");
+
+                copy1 = fdset_put_dup(fds, m->user_lookup_fds[1]);
+                if (copy1 < 0)
+                        return log_error_errno(copy1, "Failed to add user lookup fd to serialization: %m");
+
+                (void) serialize_item_format(f, "user-lookup", "%i %i", copy0, copy1);
+        }
+
+        bus_track_serialize(m->subscribed, f, "subscribed");
+
+        r = dynamic_user_serialize(m, f, fds);
+        if (r < 0)
+                return r;
+
+        manager_serialize_uid_refs(m, f);
+        manager_serialize_gid_refs(m, f);
+
+        r = exec_runtime_serialize(m, f, fds);
+        if (r < 0)
+                return r;
+
+        (void) fputc('\n', f);
+
+        HASHMAP_FOREACH_KEY(u, t, m->units) {
+                if (u->id != t)
+                        continue;
+
+                r = unit_serialize(u, f, fds, switching_root);
+                if (r < 0)
+                        return r;
+        }
+
+        r = fflush_and_check(f);
+        if (r < 0)
+                return log_error_errno(r, "Failed to flush serialization: %m");
+
+        r = bus_fdset_add_all(m, fds);
+        if (r < 0)
+                return log_error_errno(r, "Failed to add bus sockets to serialization: %m");
+
+        return 0;
+}
+
+static int manager_deserialize_one_unit(Manager *m, const char *name, FILE *f, FDSet *fds) {
+        Unit *u;
+        int r;
+
+        r = manager_load_unit(m, name, NULL, NULL, &u);
+        if (r < 0) {
+                if (r == -ENOMEM)
+                        return r;
+                return log_notice_errno(r, "Failed to load unit \"%s\", skipping deserialization: %m", name);
+        }
+
+        r = unit_deserialize(u, f, fds);
+        if (r < 0) {
+                if (r == -ENOMEM)
+                        return r;
+                return log_notice_errno(r, "Failed to deserialize unit \"%s\", skipping: %m", name);
+        }
+
+        return 0;
+}
+
+static int manager_deserialize_units(Manager *m, FILE *f, FDSet *fds) {
+        const char *unit_name;
+        int r;
+
+        for (;;) {
+                _cleanup_free_ char *line = NULL;
+                /* Start marker */
+                r = read_line(f, LONG_LINE_MAX, &line);
+                if (r < 0)
+                        return log_error_errno(r, "Failed to read serialization line: %m");
+                if (r == 0)
+                        break;
+
+                unit_name = strstrip(line);
+
+                r = manager_deserialize_one_unit(m, unit_name, f, fds);
+                if (r == -ENOMEM)
+                        return r;
+                if (r < 0) {
+                        r = unit_deserialize_skip(f);
+                        if (r < 0)
+                                return r;
+                }
+        }
+
+        return 0;
+}
+
+static void manager_deserialize_uid_refs_one_internal(
+                Hashmap** uid_refs,
+                const char *value) {
+
+        uid_t uid;
+        uint32_t c;
+        int r;
+
+        assert(uid_refs);
+        assert(value);
+
+        r = parse_uid(value, &uid);
+        if (r < 0 || uid == 0) {
+                log_debug("Unable to parse UID/GID reference serialization: " UID_FMT, uid);
+                return;
+        }
+
+        if (hashmap_ensure_allocated(uid_refs, &trivial_hash_ops) < 0) {
+                log_oom();
+                return;
+        }
+
+        c = PTR_TO_UINT32(hashmap_get(*uid_refs, UID_TO_PTR(uid)));
+        if (c & DESTROY_IPC_FLAG)
+                return;
+
+        c |= DESTROY_IPC_FLAG;
+
+        r = hashmap_replace(*uid_refs, UID_TO_PTR(uid), UINT32_TO_PTR(c));
+        if (r < 0) {
+                log_debug_errno(r, "Failed to add UID/GID reference entry: %m");
+                return;
+        }
+}
+
+static void manager_deserialize_uid_refs_one(Manager *m, const char *value) {
+        manager_deserialize_uid_refs_one_internal(&m->uid_refs, value);
+}
+
+static void manager_deserialize_gid_refs_one(Manager *m, const char *value) {
+        manager_deserialize_uid_refs_one_internal(&m->gid_refs, value);
+}
+
+int manager_deserialize(Manager *m, FILE *f, FDSet *fds) {
+        int r = 0;
+
+        assert(m);
+        assert(f);
+
+        if (DEBUG_LOGGING) {
+                if (fdset_isempty(fds))
+                        log_debug("No file descriptors passed");
+                else {
+                        int fd;
+
+                        FDSET_FOREACH(fd, fds) {
+                                _cleanup_free_ char *fn = NULL;
+
+                                r = fd_get_path(fd, &fn);
+                                if (r < 0)
+                                        log_debug_errno(r, "Received serialized fd %i → %m", fd);
+                                else
+                                        log_debug("Received serialized fd %i → %s", fd, strna(fn));
+                        }
+                }
+        }
+
+        log_debug("Deserializing state...");
+
+        /* If we are not in reload mode yet, enter it now. Not that this is recursive, a caller might already have
+         * increased it to non-zero, which is why we just increase it by one here and down again at the end of this
+         * call. */
+        _cleanup_(manager_reloading_stopp) _unused_ Manager *reloading = manager_reloading_start(m);
+
+        for (;;) {
+                _cleanup_free_ char *line = NULL;
+                const char *val, *l;
+
+                r = read_line(f, LONG_LINE_MAX, &line);
+                if (r < 0)
+                        return log_error_errno(r, "Failed to read serialization line: %m");
+                if (r == 0)
+                        break;
+
+                l = strstrip(line);
+                if (isempty(l)) /* end marker */
+                        break;
+
+                if ((val = startswith(l, "current-job-id="))) {
+                        uint32_t id;
+
+                        if (safe_atou32(val, &id) < 0)
+                                log_notice("Failed to parse current job id value '%s', ignoring.", val);
+                        else
+                                m->current_job_id = MAX(m->current_job_id, id);
+
+                } else if ((val = startswith(l, "n-installed-jobs="))) {
+                        uint32_t n;
+
+                        if (safe_atou32(val, &n) < 0)
+                                log_notice("Failed to parse installed jobs counter '%s', ignoring.", val);
+                        else
+                                m->n_installed_jobs += n;
+
+                } else if ((val = startswith(l, "n-failed-jobs="))) {
+                        uint32_t n;
+
+                        if (safe_atou32(val, &n) < 0)
+                                log_notice("Failed to parse failed jobs counter '%s', ignoring.", val);
+                        else
+                                m->n_failed_jobs += n;
+
+                } else if ((val = startswith(l, "taint-usr="))) {
+                        int b;
+
+                        b = parse_boolean(val);
+                        if (b < 0)
+                                log_notice("Failed to parse taint /usr flag '%s', ignoring.", val);
+                        else
+                                m->taint_usr = m->taint_usr || b;
+
+                } else if ((val = startswith(l, "ready-sent="))) {
+                        int b;
+
+                        b = parse_boolean(val);
+                        if (b < 0)
+                                log_notice("Failed to parse ready-sent flag '%s', ignoring.", val);
+                        else
+                                m->ready_sent = m->ready_sent || b;
+
+                } else if ((val = startswith(l, "taint-logged="))) {
+                        int b;
+
+                        b = parse_boolean(val);
+                        if (b < 0)
+                                log_notice("Failed to parse taint-logged flag '%s', ignoring.", val);
+                        else
+                                m->taint_logged = m->taint_logged || b;
+
+                } else if ((val = startswith(l, "service-watchdogs="))) {
+                        int b;
+
+                        b = parse_boolean(val);
+                        if (b < 0)
+                                log_notice("Failed to parse service-watchdogs flag '%s', ignoring.", val);
+                        else
+                                m->service_watchdogs = b;
+
+                } else if ((val = startswith(l, "honor-device-enumeration="))) {
+                        int b;
+
+                        b = parse_boolean(val);
+                        if (b < 0)
+                                log_notice("Failed to parse honor-device-enumeration flag '%s', ignoring.", val);
+                        else
+                                m->honor_device_enumeration = b;
+
+                } else if ((val = startswith(l, "show-status-overridden="))) {
+                        ShowStatus s;
+
+                        s = show_status_from_string(val);
+                        if (s < 0)
+                                log_notice("Failed to parse show-status-overridden flag '%s', ignoring.", val);
+                        else
+                                manager_override_show_status(m, s, "deserialize");
+
+                } else if ((val = startswith(l, "log-level-override="))) {
+                        int level;
+
+                        level = log_level_from_string(val);
+                        if (level < 0)
+                                log_notice("Failed to parse log-level-override value '%s', ignoring.", val);
+                        else
+                                manager_override_log_level(m, level);
+
+                } else if ((val = startswith(l, "log-target-override="))) {
+                        LogTarget target;
+
+                        target = log_target_from_string(val);
+                        if (target < 0)
+                                log_notice("Failed to parse log-target-override value '%s', ignoring.", val);
+                        else
+                                manager_override_log_target(m, target);
+
+                } else if ((val = startswith(l, "runtime-watchdog-overridden="))) {
+                        usec_t t;
+
+                        if (deserialize_usec(val, &t) < 0)
+                                log_notice("Failed to parse runtime-watchdog-overridden value '%s', ignoring.", val);
+                        else
+                                manager_override_watchdog(m, WATCHDOG_RUNTIME, t);
+
+                } else if ((val = startswith(l, "reboot-watchdog-overridden="))) {
+                        usec_t t;
+
+                        if (deserialize_usec(val, &t) < 0)
+                                log_notice("Failed to parse reboot-watchdog-overridden value '%s', ignoring.", val);
+                        else
+                                manager_override_watchdog(m, WATCHDOG_REBOOT, t);
+
+                } else if ((val = startswith(l, "kexec-watchdog-overridden="))) {
+                        usec_t t;
+
+                        if (deserialize_usec(val, &t) < 0)
+                                log_notice("Failed to parse kexec-watchdog-overridden value '%s', ignoring.", val);
+                        else
+                                manager_override_watchdog(m, WATCHDOG_KEXEC, t);
+
+                } else if (startswith(l, "env=")) {
+                        r = deserialize_environment(l + 4, &m->client_environment);
+                        if (r < 0)
+                                log_notice_errno(r, "Failed to parse environment entry: \"%s\", ignoring: %m", l);
+
+                } else if ((val = startswith(l, "notify-fd="))) {
+                        int fd;
+
+                        if (safe_atoi(val, &fd) < 0 || fd < 0 || !fdset_contains(fds, fd))
+                                log_notice("Failed to parse notify fd, ignoring: \"%s\"", val);
+                        else {
+                                m->notify_event_source = sd_event_source_disable_unref(m->notify_event_source);
+                                safe_close(m->notify_fd);
+                                m->notify_fd = fdset_remove(fds, fd);
+                        }
+
+                } else if ((val = startswith(l, "notify-socket="))) {
+                        r = free_and_strdup(&m->notify_socket, val);
+                        if (r < 0)
+                                return r;
+
+                } else if ((val = startswith(l, "cgroups-agent-fd="))) {
+                        int fd;
+
+                        if (safe_atoi(val, &fd) < 0 || fd < 0 || !fdset_contains(fds, fd))
+                                log_notice("Failed to parse cgroups agent fd, ignoring.: %s", val);
+                        else {
+                                m->cgroups_agent_event_source = sd_event_source_disable_unref(m->cgroups_agent_event_source);
+                                safe_close(m->cgroups_agent_fd);
+                                m->cgroups_agent_fd = fdset_remove(fds, fd);
+                        }
+
+                } else if ((val = startswith(l, "user-lookup="))) {
+                        int fd0, fd1;
+
+                        if (sscanf(val, "%i %i", &fd0, &fd1) != 2 || fd0 < 0 || fd1 < 0 || fd0 == fd1 || !fdset_contains(fds, fd0) || !fdset_contains(fds, fd1))
+                                log_notice("Failed to parse user lookup fd, ignoring: %s", val);
+                        else {
+                                m->user_lookup_event_source = sd_event_source_disable_unref(m->user_lookup_event_source);
+                                safe_close_pair(m->user_lookup_fds);
+                                m->user_lookup_fds[0] = fdset_remove(fds, fd0);
+                                m->user_lookup_fds[1] = fdset_remove(fds, fd1);
+                        }
+
+                } else if ((val = startswith(l, "dynamic-user=")))
+                        dynamic_user_deserialize_one(m, val, fds);
+                else if ((val = startswith(l, "destroy-ipc-uid=")))
+                        manager_deserialize_uid_refs_one(m, val);
+                else if ((val = startswith(l, "destroy-ipc-gid=")))
+                        manager_deserialize_gid_refs_one(m, val);
+                else if ((val = startswith(l, "exec-runtime=")))
+                        (void) exec_runtime_deserialize_one(m, val, fds);
+                else if ((val = startswith(l, "subscribed="))) {
+
+                        if (strv_extend(&m->deserialized_subscribed, val) < 0)
+                                return -ENOMEM;
+
+                } else {
+                        ManagerTimestamp q;
+
+                        for (q = 0; q < _MANAGER_TIMESTAMP_MAX; q++) {
+                                val = startswith(l, manager_timestamp_to_string(q));
+                                if (!val)
+                                        continue;
+
+                                val = startswith(val, "-timestamp=");
+                                if (val)
+                                        break;
+                        }
+
+                        if (q < _MANAGER_TIMESTAMP_MAX) /* found it */
+                                (void) deserialize_dual_timestamp(val, m->timestamps + q);
+                        else if (!startswith(l, "kdbus-fd=")) /* ignore kdbus */
+                                log_notice("Unknown serialization item '%s', ignoring.", l);
+                }
+        }
+
+        return manager_deserialize_units(m, f, fds);
+}
diff --git a/src/core/manager-serialize.h b/src/core/manager-serialize.h
new file mode 100644 (file)
index 0000000..c52261e
--- /dev/null
@@ -0,0 +1,13 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+#pragma once
+
+#include <stdbool.h>
+
+#include "manager.h"
+#include "fdset.h"
+
+#define DESTROY_IPC_FLAG (UINT32_C(1) << 31)
+
+int manager_open_serialization(Manager *m, FILE **ret_f);
+int manager_serialize(Manager *m, FILE *f, FDSet *fds, bool switching_root);
+int manager_deserialize(Manager *m, FILE *f, FDSet *fds);
index 888443734701eb3291387746c132785efe8df78f..24dfe9fc06b831f2ed7d1cf5fe557a45b9a65cf1 100644 (file)
@@ -56,6 +56,7 @@
 #include "macro.h"
 #include "manager.h"
 #include "manager-dump.h"
+#include "manager-serialize.h"
 #include "memory-util.h"
 #include "mkdir.h"
 #include "parse-util.h"
@@ -66,7 +67,6 @@
 #include "rlimit-util.h"
 #include "rm-rf.h"
 #include "selinux-util.h"
-#include "serialize.h"
 #include "signal-util.h"
 #include "socket-util.h"
 #include "special.h"
@@ -82,7 +82,6 @@
 #include "transaction.h"
 #include "umask-util.h"
 #include "unit-name.h"
-#include "unit-serialize.h"
 #include "user-util.h"
 #include "virt.h"
 #include "watchdog.h"
@@ -118,9 +117,19 @@ static int manager_run_generators(Manager *m);
 static void manager_vacuum(Manager *m);
 
 static usec_t manager_watch_jobs_next_time(Manager *m) {
-        return usec_add(now(CLOCK_MONOTONIC),
-                        show_status_on(m->show_status) ? JOBS_IN_PROGRESS_WAIT_USEC :
-                                                         JOBS_IN_PROGRESS_QUIET_WAIT_USEC);
+        usec_t timeout;
+
+        if (MANAGER_IS_USER(m))
+                /* Let the user manager without a timeout show status quickly, so the system manager can make
+                 * use of it, if it wants to. */
+                timeout = JOBS_IN_PROGRESS_WAIT_USEC * 2 / 3;
+        else if (show_status_on(m->show_status))
+                /* When status is on, just use the usual timeout. */
+                timeout = JOBS_IN_PROGRESS_WAIT_USEC;
+        else
+                timeout = JOBS_IN_PROGRESS_QUIET_WAIT_USEC;
+
+        return usec_add(now(CLOCK_MONOTONIC), timeout);
 }
 
 static void manager_watch_jobs_in_progress(Manager *m) {
@@ -200,12 +209,10 @@ static void manager_flip_auto_status(Manager *m, bool enable, const char *reason
 }
 
 static void manager_print_jobs_in_progress(Manager *m) {
-        _cleanup_free_ char *job_of_n = NULL;
         Job *j;
         unsigned counter = 0, print_nr;
         char cylon[6 + CYLON_BUFFER_EXTRA + 1];
         unsigned cylon_pos;
-        char time[FORMAT_TIMESPAN_MAX], limit[FORMAT_TIMESPAN_MAX] = "no limit";
         uint64_t x;
 
         assert(m);
@@ -231,28 +238,51 @@ static void manager_print_jobs_in_progress(Manager *m) {
 
         m->jobs_in_progress_iteration++;
 
-        if (m->n_running_jobs > 1) {
-                if (asprintf(&job_of_n, "(%u of %u) ", counter, m->n_running_jobs) < 0)
-                        job_of_n = NULL;
-        }
+        char job_of_n[STRLEN("( of ) ") + DECIMAL_STR_MAX(unsigned)*2] = "";
+        if (m->n_running_jobs > 1)
+                xsprintf(job_of_n, "(%u of %u) ", counter, m->n_running_jobs);
 
-        format_timespan(time, sizeof(time), now(CLOCK_MONOTONIC) - j->begin_usec, 1*USEC_PER_SEC);
-        if (job_get_timeout(j, &x) > 0)
-                format_timespan(limit, sizeof(limit), x - j->begin_usec, 1*USEC_PER_SEC);
+        bool have_timeout = job_get_timeout(j, &x) > 0;
 
         /* We want to use enough information for the user to identify previous lines talking about the same
          * unit, but keep the message as short as possible. So if 'Starting foo.service' or 'Starting
-         * foo.service (Description)' were used, 'foo.service' is enough here. On the other hand, if we used
+         * foo.service - Description' were used, 'foo.service' is enough here. On the other hand, if we used
          * 'Starting Description' before, then we shall also use 'Description' here. So we pass NULL as the
          * second argument to unit_status_string(). */
         const char *ident = unit_status_string(j->unit, NULL);
 
-        manager_status_printf(m, STATUS_TYPE_EPHEMERAL, cylon,
-                              "%sA %s job is running for %s (%s / %s)",
-                              strempty(job_of_n),
-                              job_type_to_string(j->type),
-                              ident,
-                              time, limit);
+        const char *time = FORMAT_TIMESPAN(now(CLOCK_MONOTONIC) - j->begin_usec, 1*USEC_PER_SEC);
+        const char *limit = have_timeout ? FORMAT_TIMESPAN(x - j->begin_usec, 1*USEC_PER_SEC) : "no limit";
+
+        if (m->status_unit_format == STATUS_UNIT_FORMAT_DESCRIPTION)
+                /* When using 'Description', we effectively don't have enough space to show the nested status
+                 * without ellipsization, so let's not even try. */
+                manager_status_printf(m, STATUS_TYPE_EPHEMERAL, cylon,
+                                      "%sA %s job is running for %s (%s / %s)",
+                                      job_of_n,
+                                      job_type_to_string(j->type),
+                                      ident,
+                                      time, limit);
+        else {
+                const char *status_text = unit_status_text(j->unit);
+
+                manager_status_printf(m, STATUS_TYPE_EPHEMERAL, cylon,
+                                      "%sJob %s/%s running (%s / %s)%s%s",
+                                      job_of_n,
+                                      ident,
+                                      job_type_to_string(j->type),
+                                      time, limit,
+                                      status_text ? ": " : "",
+                                      strempty(status_text));
+        }
+
+        sd_notifyf(false,
+                   "STATUS=%sUser job %s/%s running (%s / %s)...",
+                   job_of_n,
+                   ident,
+                   job_type_to_string(j->type),
+                   time, limit);
+        m->status_ready = false;
 }
 
 static int have_ask_password(void) {
@@ -548,8 +578,7 @@ static int manager_setup_signals(Manager *m) {
                         SIGRTMIN+22, /* systemd: set log level to LOG_DEBUG */
                         SIGRTMIN+23, /* systemd: set log level to LOG_INFO */
                         SIGRTMIN+24, /* systemd: Immediate exit (--user only) */
-
-                        /* .. one free signal here ... */
+                        SIGRTMIN+25, /* systemd: reexecute manager */
 
                         /* Apparently Linux on hppa had fewer RT signals until v3.18,
                          * SIGRTMAX was SIGRTMIN+25, and then SIGRTMIN was lowered,
@@ -624,9 +653,7 @@ static char** sanitize_environment(char **l) {
                         NULL);
 
         /* Let's order the environment alphabetically, just to make it pretty */
-        strv_sort(l);
-
-        return l;
+        return strv_sort(l);
 }
 
 int manager_default_environment(Manager *m) {
@@ -1689,11 +1716,11 @@ static void manager_ready(Manager *m) {
         m->honor_device_enumeration = true;
 }
 
-static Manager* manager_reloading_start(Manager *m) {
+Manager* manager_reloading_start(Manager *m) {
         m->n_reloading++;
         return m;
 }
-static void manager_reloading_stopp(Manager **m) {
+void manager_reloading_stopp(Manager **m) {
         if (*m) {
                 assert((*m)->n_reloading > 0);
                 (*m)->n_reloading--;
@@ -2619,15 +2646,19 @@ turn_off:
         return 0;
 }
 
-static void manager_start_target(Manager *m, const char *name, JobMode mode) {
-        _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
-        int r;
+static void manager_start_special(Manager *m, const char *name, JobMode mode) {
+        Job *job;
+
+        if (manager_add_job_by_name_and_warn(m, JOB_START, name, mode, NULL, &job) < 0)
+                return;
 
-        log_debug("Activating special unit %s", name);
+        const char *s = unit_status_string(job->unit, NULL);
 
-        r = manager_add_job_by_name(m, JOB_START, name, mode, NULL, &error, NULL);
-        if (r < 0)
-                log_error("Failed to enqueue %s job: %s", name, bus_error_message(&error, r));
+        log_info("Activating special unit %s...", s);
+
+        sd_notifyf(false,
+                   "STATUS=Activating special unit %s...", s);
+        m->status_ready = false;
 }
 
 static void manager_handle_ctrl_alt_del(Manager *m) {
@@ -2636,7 +2667,7 @@ static void manager_handle_ctrl_alt_del(Manager *m) {
          * unless it was disabled in system.conf */
 
         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);
+                manager_start_special(m, SPECIAL_CTRL_ALT_DEL_TARGET, JOB_REPLACE_IRREVERSIBLY);
         else
                 emergency_action(m, m->cad_burst_action, EMERGENCY_ACTION_WARN, NULL, -1,
                                 "Ctrl-Alt-Del was pressed more than 7 times within 2s");
@@ -2700,21 +2731,20 @@ static int manager_dispatch_signal_fd(sd_event_source *source, int fd, uint32_t
                 if (MANAGER_IS_SYSTEM(m))
                         manager_handle_ctrl_alt_del(m);
                 else
-                        manager_start_target(m, SPECIAL_EXIT_TARGET,
-                                             JOB_REPLACE_IRREVERSIBLY);
+                        manager_start_special(m, SPECIAL_EXIT_TARGET, JOB_REPLACE_IRREVERSIBLY);
                 break;
 
         case SIGWINCH:
                 /* This is a nop on non-init */
                 if (MANAGER_IS_SYSTEM(m))
-                        manager_start_target(m, SPECIAL_KBREQUEST_TARGET, JOB_REPLACE);
+                        manager_start_special(m, SPECIAL_KBREQUEST_TARGET, JOB_REPLACE);
 
                 break;
 
         case SIGPWR:
                 /* This is a nop on non-init */
                 if (MANAGER_IS_SYSTEM(m))
-                        manager_start_target(m, SPECIAL_SIGPWR_TARGET, JOB_REPLACE);
+                        manager_start_special(m, SPECIAL_SIGPWR_TARGET, JOB_REPLACE);
 
                 break;
 
@@ -2726,10 +2756,8 @@ static int manager_dispatch_signal_fd(sd_event_source *source, int fd, uint32_t
 
                         if (MANAGER_IS_SYSTEM(m))
                                 (void) bus_init_system(m);
-                } else {
-                        log_info("Starting D-Bus service...");
-                        manager_start_target(m, SPECIAL_DBUS_SERVICE, JOB_REPLACE);
-                }
+                } else
+                        manager_start_special(m, SPECIAL_DBUS_SERVICE, JOB_REPLACE);
 
                 break;
 
@@ -2780,8 +2808,7 @@ static int manager_dispatch_signal_fd(sd_event_source *source, int fd, uint32_t
                 if ((int) sfsi.ssi_signo >= SIGRTMIN+0 &&
                     (int) sfsi.ssi_signo < SIGRTMIN+(int) ELEMENTSOF(target_table)) {
                         int idx = (int) sfsi.ssi_signo - SIGRTMIN;
-                        manager_start_target(m, target_table[idx].target,
-                                             target_table[idx].mode);
+                        manager_start_special(m, target_table[idx].target, target_table[idx].mode);
                         break;
                 }
 
@@ -2818,6 +2845,10 @@ static int manager_dispatch_signal_fd(sd_event_source *source, int fd, uint32_t
                         /* This is a nop on init */
                         break;
 
+                case 25:
+                        m->objective = MANAGER_REEXECUTE;
+                        break;
+
                 case 26:
                 case 29: /* compatibility: used to be mapped to LOG_TARGET_SYSLOG_OR_KMSG */
                         manager_restore_original_log_target(m);
@@ -3146,10 +3177,8 @@ void manager_send_unit_plymouth(Manager *m, Unit *u) {
                 return;
         }
 
-        if (asprintf(&message, "U\002%c%s%n", (int) (strlen(u->id) + 1), u->id, &n) < 0) {
-                log_oom();
-                return;
-        }
+        if (asprintf(&message, "U\002%c%s%n", (int) (strlen(u->id) + 1), u->id, &n) < 0)
+                return (void) log_oom();
 
         errno = 0;
         if (write(fd, message, n + 1) != n + 1)
@@ -3157,242 +3186,6 @@ void manager_send_unit_plymouth(Manager *m, Unit *u) {
                         log_error_errno(errno, "Failed to write Plymouth message: %m");
 }
 
-int manager_open_serialization(Manager *m, FILE **_f) {
-        _cleanup_close_ int fd = -1;
-        FILE *f;
-
-        assert(_f);
-
-        fd = open_serialization_fd("systemd-state");
-        if (fd < 0)
-                return fd;
-
-        f = take_fdopen(&fd, "w+");
-        if (!f)
-                return -errno;
-
-        *_f = f;
-        return 0;
-}
-
-static bool manager_timestamp_shall_serialize(ManagerTimestamp t) {
-
-        if (!in_initrd())
-                return true;
-
-        /* The following timestamps only apply to the host system, hence only serialize them there */
-        return !IN_SET(t,
-                       MANAGER_TIMESTAMP_USERSPACE, MANAGER_TIMESTAMP_FINISH,
-                       MANAGER_TIMESTAMP_SECURITY_START, MANAGER_TIMESTAMP_SECURITY_FINISH,
-                       MANAGER_TIMESTAMP_GENERATORS_START, MANAGER_TIMESTAMP_GENERATORS_FINISH,
-                       MANAGER_TIMESTAMP_UNITS_LOAD_START, MANAGER_TIMESTAMP_UNITS_LOAD_FINISH);
-}
-
-#define DESTROY_IPC_FLAG (UINT32_C(1) << 31)
-
-static void manager_serialize_uid_refs_internal(
-                FILE *f,
-                Hashmap *uid_refs,
-                const char *field_name) {
-
-        void *p, *k;
-
-        assert(f);
-        assert(field_name);
-
-        /* Serialize the UID reference table. Or actually, just the IPC destruction flag of it, as
-         * the actual counter of it is better rebuild after a reload/reexec. */
-
-        HASHMAP_FOREACH_KEY(p, k, uid_refs) {
-                uint32_t c;
-                uid_t uid;
-
-                uid = PTR_TO_UID(k);
-                c = PTR_TO_UINT32(p);
-
-                if (!(c & DESTROY_IPC_FLAG))
-                        continue;
-
-                (void) serialize_item_format(f, field_name, UID_FMT, uid);
-        }
-}
-
-static void manager_serialize_uid_refs(Manager *m, FILE *f) {
-        manager_serialize_uid_refs_internal(f, m->uid_refs, "destroy-ipc-uid");
-}
-
-static void manager_serialize_gid_refs(Manager *m, FILE *f) {
-        manager_serialize_uid_refs_internal(f, m->gid_refs, "destroy-ipc-gid");
-}
-
-int manager_serialize(
-                Manager *m,
-                FILE *f,
-                FDSet *fds,
-                bool switching_root) {
-
-        const char *t;
-        Unit *u;
-        int r;
-
-        assert(m);
-        assert(f);
-        assert(fds);
-
-        _cleanup_(manager_reloading_stopp) _unused_ Manager *reloading = manager_reloading_start(m);
-
-        (void) serialize_item_format(f, "current-job-id", "%" PRIu32, m->current_job_id);
-        (void) serialize_item_format(f, "n-installed-jobs", "%u", m->n_installed_jobs);
-        (void) serialize_item_format(f, "n-failed-jobs", "%u", m->n_failed_jobs);
-        (void) serialize_bool(f, "taint-usr", m->taint_usr);
-        (void) serialize_bool(f, "ready-sent", m->ready_sent);
-        (void) serialize_bool(f, "taint-logged", m->taint_logged);
-        (void) serialize_bool(f, "service-watchdogs", m->service_watchdogs);
-
-        /* After switching root, udevd has not been started yet. So, enumeration results should not be emitted. */
-        (void) serialize_bool(f, "honor-device-enumeration", !switching_root);
-
-        if (m->show_status_overridden != _SHOW_STATUS_INVALID)
-                (void) serialize_item(f, "show-status-overridden",
-                                      show_status_to_string(m->show_status_overridden));
-
-        if (m->log_level_overridden)
-                (void) serialize_item_format(f, "log-level-override", "%i", log_get_max_level());
-        if (m->log_target_overridden)
-                (void) serialize_item(f, "log-target-override", log_target_to_string(log_get_target()));
-
-        (void) serialize_usec(f, "runtime-watchdog-overridden", m->watchdog_overridden[WATCHDOG_RUNTIME]);
-        (void) serialize_usec(f, "reboot-watchdog-overridden", m->watchdog_overridden[WATCHDOG_REBOOT]);
-        (void) serialize_usec(f, "kexec-watchdog-overridden", m->watchdog_overridden[WATCHDOG_KEXEC]);
-
-        for (ManagerTimestamp q = 0; q < _MANAGER_TIMESTAMP_MAX; q++) {
-                _cleanup_free_ char *joined = NULL;
-
-                if (!manager_timestamp_shall_serialize(q))
-                        continue;
-
-                joined = strjoin(manager_timestamp_to_string(q), "-timestamp");
-                if (!joined)
-                        return log_oom();
-
-                (void) serialize_dual_timestamp(f, joined, m->timestamps + q);
-        }
-
-        if (!switching_root)
-                (void) serialize_strv(f, "env", m->client_environment);
-
-        if (m->notify_fd >= 0) {
-                r = serialize_fd(f, fds, "notify-fd", m->notify_fd);
-                if (r < 0)
-                        return r;
-
-                (void) serialize_item(f, "notify-socket", m->notify_socket);
-        }
-
-        if (m->cgroups_agent_fd >= 0) {
-                r = serialize_fd(f, fds, "cgroups-agent-fd", m->cgroups_agent_fd);
-                if (r < 0)
-                        return r;
-        }
-
-        if (m->user_lookup_fds[0] >= 0) {
-                int copy0, copy1;
-
-                copy0 = fdset_put_dup(fds, m->user_lookup_fds[0]);
-                if (copy0 < 0)
-                        return log_error_errno(copy0, "Failed to add user lookup fd to serialization: %m");
-
-                copy1 = fdset_put_dup(fds, m->user_lookup_fds[1]);
-                if (copy1 < 0)
-                        return log_error_errno(copy1, "Failed to add user lookup fd to serialization: %m");
-
-                (void) serialize_item_format(f, "user-lookup", "%i %i", copy0, copy1);
-        }
-
-        bus_track_serialize(m->subscribed, f, "subscribed");
-
-        r = dynamic_user_serialize(m, f, fds);
-        if (r < 0)
-                return r;
-
-        manager_serialize_uid_refs(m, f);
-        manager_serialize_gid_refs(m, f);
-
-        r = exec_runtime_serialize(m, f, fds);
-        if (r < 0)
-                return r;
-
-        (void) fputc('\n', f);
-
-        HASHMAP_FOREACH_KEY(u, t, m->units) {
-                if (u->id != t)
-                        continue;
-
-                r = unit_serialize(u, f, fds, switching_root);
-                if (r < 0)
-                        return r;
-        }
-
-        r = fflush_and_check(f);
-        if (r < 0)
-                return log_error_errno(r, "Failed to flush serialization: %m");
-
-        r = bus_fdset_add_all(m, fds);
-        if (r < 0)
-                return log_error_errno(r, "Failed to add bus sockets to serialization: %m");
-
-        return 0;
-}
-
-static int manager_deserialize_one_unit(Manager *m, const char *name, FILE *f, FDSet *fds) {
-        Unit *u;
-        int r;
-
-        r = manager_load_unit(m, name, NULL, NULL, &u);
-        if (r < 0) {
-                if (r == -ENOMEM)
-                        return r;
-                return log_notice_errno(r, "Failed to load unit \"%s\", skipping deserialization: %m", name);
-        }
-
-        r = unit_deserialize(u, f, fds);
-        if (r < 0) {
-                if (r == -ENOMEM)
-                        return r;
-                return log_notice_errno(r, "Failed to deserialize unit \"%s\", skipping: %m", name);
-        }
-
-        return 0;
-}
-
-static int manager_deserialize_units(Manager *m, FILE *f, FDSet *fds) {
-        const char *unit_name;
-        int r;
-
-        for (;;) {
-                _cleanup_free_ char *line = NULL;
-                /* Start marker */
-                r = read_line(f, LONG_LINE_MAX, &line);
-                if (r < 0)
-                        return log_error_errno(r, "Failed to read serialization line: %m");
-                if (r == 0)
-                        break;
-
-                unit_name = strstrip(line);
-
-                r = manager_deserialize_one_unit(m, unit_name, f, fds);
-                if (r == -ENOMEM)
-                        return r;
-                if (r < 0) {
-                        r = unit_deserialize_skip(f);
-                        if (r < 0)
-                                return r;
-                }
-        }
-
-        return 0;
-}
-
 usec_t manager_get_watchdog(Manager *m, WatchdogType t) {
         assert(m);
 
@@ -3477,294 +3270,6 @@ void manager_retry_runtime_watchdog(Manager *m) {
                 m->runtime_watchdog_running = true;
 }
 
-static void manager_deserialize_uid_refs_one_internal(
-                Hashmap** uid_refs,
-                const char *value) {
-
-        uid_t uid;
-        uint32_t c;
-        int r;
-
-        assert(uid_refs);
-        assert(value);
-
-        r = parse_uid(value, &uid);
-        if (r < 0 || uid == 0) {
-                log_debug("Unable to parse UID/GID reference serialization: " UID_FMT, uid);
-                return;
-        }
-
-        if (hashmap_ensure_allocated(uid_refs, &trivial_hash_ops) < 0) {
-                log_oom();
-                return;
-        }
-
-        c = PTR_TO_UINT32(hashmap_get(*uid_refs, UID_TO_PTR(uid)));
-        if (c & DESTROY_IPC_FLAG)
-                return;
-
-        c |= DESTROY_IPC_FLAG;
-
-        r = hashmap_replace(*uid_refs, UID_TO_PTR(uid), UINT32_TO_PTR(c));
-        if (r < 0) {
-                log_debug_errno(r, "Failed to add UID/GID reference entry: %m");
-                return;
-        }
-}
-
-static void manager_deserialize_uid_refs_one(Manager *m, const char *value) {
-        manager_deserialize_uid_refs_one_internal(&m->uid_refs, value);
-}
-
-static void manager_deserialize_gid_refs_one(Manager *m, const char *value) {
-        manager_deserialize_uid_refs_one_internal(&m->gid_refs, value);
-}
-
-int manager_deserialize(Manager *m, FILE *f, FDSet *fds) {
-        int r = 0;
-
-        assert(m);
-        assert(f);
-
-        if (DEBUG_LOGGING) {
-                if (fdset_isempty(fds))
-                        log_debug("No file descriptors passed");
-                else {
-                        int fd;
-
-                        FDSET_FOREACH(fd, fds) {
-                                _cleanup_free_ char *fn = NULL;
-
-                                r = fd_get_path(fd, &fn);
-                                if (r < 0)
-                                        log_debug_errno(r, "Received serialized fd %i → %m", fd);
-                                else
-                                        log_debug("Received serialized fd %i → %s", fd, strna(fn));
-                        }
-                }
-        }
-
-        log_debug("Deserializing state...");
-
-        /* If we are not in reload mode yet, enter it now. Not that this is recursive, a caller might already have
-         * increased it to non-zero, which is why we just increase it by one here and down again at the end of this
-         * call. */
-        _cleanup_(manager_reloading_stopp) _unused_ Manager *reloading = manager_reloading_start(m);
-
-        for (;;) {
-                _cleanup_free_ char *line = NULL;
-                const char *val, *l;
-
-                r = read_line(f, LONG_LINE_MAX, &line);
-                if (r < 0)
-                        return log_error_errno(r, "Failed to read serialization line: %m");
-                if (r == 0)
-                        break;
-
-                l = strstrip(line);
-                if (isempty(l)) /* end marker */
-                        break;
-
-                if ((val = startswith(l, "current-job-id="))) {
-                        uint32_t id;
-
-                        if (safe_atou32(val, &id) < 0)
-                                log_notice("Failed to parse current job id value '%s', ignoring.", val);
-                        else
-                                m->current_job_id = MAX(m->current_job_id, id);
-
-                } else if ((val = startswith(l, "n-installed-jobs="))) {
-                        uint32_t n;
-
-                        if (safe_atou32(val, &n) < 0)
-                                log_notice("Failed to parse installed jobs counter '%s', ignoring.", val);
-                        else
-                                m->n_installed_jobs += n;
-
-                } else if ((val = startswith(l, "n-failed-jobs="))) {
-                        uint32_t n;
-
-                        if (safe_atou32(val, &n) < 0)
-                                log_notice("Failed to parse failed jobs counter '%s', ignoring.", val);
-                        else
-                                m->n_failed_jobs += n;
-
-                } else if ((val = startswith(l, "taint-usr="))) {
-                        int b;
-
-                        b = parse_boolean(val);
-                        if (b < 0)
-                                log_notice("Failed to parse taint /usr flag '%s', ignoring.", val);
-                        else
-                                m->taint_usr = m->taint_usr || b;
-
-                } else if ((val = startswith(l, "ready-sent="))) {
-                        int b;
-
-                        b = parse_boolean(val);
-                        if (b < 0)
-                                log_notice("Failed to parse ready-sent flag '%s', ignoring.", val);
-                        else
-                                m->ready_sent = m->ready_sent || b;
-
-                } else if ((val = startswith(l, "taint-logged="))) {
-                        int b;
-
-                        b = parse_boolean(val);
-                        if (b < 0)
-                                log_notice("Failed to parse taint-logged flag '%s', ignoring.", val);
-                        else
-                                m->taint_logged = m->taint_logged || b;
-
-                } else if ((val = startswith(l, "service-watchdogs="))) {
-                        int b;
-
-                        b = parse_boolean(val);
-                        if (b < 0)
-                                log_notice("Failed to parse service-watchdogs flag '%s', ignoring.", val);
-                        else
-                                m->service_watchdogs = b;
-
-                } else if ((val = startswith(l, "honor-device-enumeration="))) {
-                        int b;
-
-                        b = parse_boolean(val);
-                        if (b < 0)
-                                log_notice("Failed to parse honor-device-enumeration flag '%s', ignoring.", val);
-                        else
-                                m->honor_device_enumeration = b;
-
-                } else if ((val = startswith(l, "show-status-overridden="))) {
-                        ShowStatus s;
-
-                        s = show_status_from_string(val);
-                        if (s < 0)
-                                log_notice("Failed to parse show-status-overridden flag '%s', ignoring.", val);
-                        else
-                                manager_override_show_status(m, s, "deserialize");
-
-                } else if ((val = startswith(l, "log-level-override="))) {
-                        int level;
-
-                        level = log_level_from_string(val);
-                        if (level < 0)
-                                log_notice("Failed to parse log-level-override value '%s', ignoring.", val);
-                        else
-                                manager_override_log_level(m, level);
-
-                } else if ((val = startswith(l, "log-target-override="))) {
-                        LogTarget target;
-
-                        target = log_target_from_string(val);
-                        if (target < 0)
-                                log_notice("Failed to parse log-target-override value '%s', ignoring.", val);
-                        else
-                                manager_override_log_target(m, target);
-
-                } else if ((val = startswith(l, "runtime-watchdog-overridden="))) {
-                        usec_t t;
-
-                        if (deserialize_usec(val, &t) < 0)
-                                log_notice("Failed to parse runtime-watchdog-overridden value '%s', ignoring.", val);
-                        else
-                                manager_override_watchdog(m, WATCHDOG_RUNTIME, t);
-
-                } else if ((val = startswith(l, "reboot-watchdog-overridden="))) {
-                        usec_t t;
-
-                        if (deserialize_usec(val, &t) < 0)
-                                log_notice("Failed to parse reboot-watchdog-overridden value '%s', ignoring.", val);
-                        else
-                                manager_override_watchdog(m, WATCHDOG_REBOOT, t);
-
-                } else if ((val = startswith(l, "kexec-watchdog-overridden="))) {
-                        usec_t t;
-
-                        if (deserialize_usec(val, &t) < 0)
-                                log_notice("Failed to parse kexec-watchdog-overridden value '%s', ignoring.", val);
-                        else
-                                manager_override_watchdog(m, WATCHDOG_KEXEC, t);
-
-                } else if (startswith(l, "env=")) {
-                        r = deserialize_environment(l + 4, &m->client_environment);
-                        if (r < 0)
-                                log_notice_errno(r, "Failed to parse environment entry: \"%s\", ignoring: %m", l);
-
-                } else if ((val = startswith(l, "notify-fd="))) {
-                        int fd;
-
-                        if (safe_atoi(val, &fd) < 0 || fd < 0 || !fdset_contains(fds, fd))
-                                log_notice("Failed to parse notify fd, ignoring: \"%s\"", val);
-                        else {
-                                m->notify_event_source = sd_event_source_disable_unref(m->notify_event_source);
-                                safe_close(m->notify_fd);
-                                m->notify_fd = fdset_remove(fds, fd);
-                        }
-
-                } else if ((val = startswith(l, "notify-socket="))) {
-                        r = free_and_strdup(&m->notify_socket, val);
-                        if (r < 0)
-                                return r;
-
-                } else if ((val = startswith(l, "cgroups-agent-fd="))) {
-                        int fd;
-
-                        if (safe_atoi(val, &fd) < 0 || fd < 0 || !fdset_contains(fds, fd))
-                                log_notice("Failed to parse cgroups agent fd, ignoring.: %s", val);
-                        else {
-                                m->cgroups_agent_event_source = sd_event_source_disable_unref(m->cgroups_agent_event_source);
-                                safe_close(m->cgroups_agent_fd);
-                                m->cgroups_agent_fd = fdset_remove(fds, fd);
-                        }
-
-                } else if ((val = startswith(l, "user-lookup="))) {
-                        int fd0, fd1;
-
-                        if (sscanf(val, "%i %i", &fd0, &fd1) != 2 || fd0 < 0 || fd1 < 0 || fd0 == fd1 || !fdset_contains(fds, fd0) || !fdset_contains(fds, fd1))
-                                log_notice("Failed to parse user lookup fd, ignoring: %s", val);
-                        else {
-                                m->user_lookup_event_source = sd_event_source_disable_unref(m->user_lookup_event_source);
-                                safe_close_pair(m->user_lookup_fds);
-                                m->user_lookup_fds[0] = fdset_remove(fds, fd0);
-                                m->user_lookup_fds[1] = fdset_remove(fds, fd1);
-                        }
-
-                } else if ((val = startswith(l, "dynamic-user=")))
-                        dynamic_user_deserialize_one(m, val, fds);
-                else if ((val = startswith(l, "destroy-ipc-uid=")))
-                        manager_deserialize_uid_refs_one(m, val);
-                else if ((val = startswith(l, "destroy-ipc-gid=")))
-                        manager_deserialize_gid_refs_one(m, val);
-                else if ((val = startswith(l, "exec-runtime=")))
-                        (void) exec_runtime_deserialize_one(m, val, fds);
-                else if ((val = startswith(l, "subscribed="))) {
-
-                        if (strv_extend(&m->deserialized_subscribed, val) < 0)
-                                return -ENOMEM;
-
-                } else {
-                        ManagerTimestamp q;
-
-                        for (q = 0; q < _MANAGER_TIMESTAMP_MAX; q++) {
-                                val = startswith(l, manager_timestamp_to_string(q));
-                                if (!val)
-                                        continue;
-
-                                val = startswith(val, "-timestamp=");
-                                if (val)
-                                        break;
-                        }
-
-                        if (q < _MANAGER_TIMESTAMP_MAX) /* found it */
-                                (void) deserialize_dual_timestamp(val, m->timestamps + q);
-                        else if (!startswith(l, "kdbus-fd=")) /* ignore kdbus */
-                                log_notice("Unknown serialization item '%s', ignoring.", l);
-                }
-        }
-
-        return manager_deserialize_units(m, f, fds);
-}
-
 int manager_reload(Manager *m) {
         _cleanup_(manager_reloading_stopp) Manager *reloading = NULL;
         _cleanup_fdset_free_ FDSet *fds = NULL;
@@ -3905,14 +3410,12 @@ static void log_taint_string(Manager *m) {
 }
 
 static void manager_notify_finished(Manager *m) {
-        char userspace[FORMAT_TIMESPAN_MAX], initrd[FORMAT_TIMESPAN_MAX], kernel[FORMAT_TIMESPAN_MAX], sum[FORMAT_TIMESPAN_MAX];
         usec_t firmware_usec, loader_usec, kernel_usec, initrd_usec, userspace_usec, total_usec;
 
         if (MANAGER_IS_TEST_RUN(m))
                 return;
 
         if (MANAGER_IS_SYSTEM(m) && detect_container() <= 0) {
-                char ts[FORMAT_TIMESPAN_MAX];
                 char buf[FORMAT_TIMESPAN_MAX + STRLEN(" (firmware) + ") + FORMAT_TIMESPAN_MAX + STRLEN(" (loader) + ")]
                         = {};
                 char *p = buf;
@@ -3928,9 +3431,9 @@ static void manager_notify_finished(Manager *m) {
                 total_usec = m->timestamps[MANAGER_TIMESTAMP_FIRMWARE].monotonic + m->timestamps[MANAGER_TIMESTAMP_FINISH].monotonic;
 
                 if (firmware_usec > 0)
-                        size = strpcpyf(&p, size, "%s (firmware) + ", format_timespan(ts, sizeof(ts), firmware_usec, USEC_PER_MSEC));
+                        size = strpcpyf(&p, size, "%s (firmware) + ", FORMAT_TIMESPAN(firmware_usec, USEC_PER_MSEC));
                 if (loader_usec > 0)
-                        size = strpcpyf(&p, size, "%s (loader) + ", format_timespan(ts, sizeof(ts), loader_usec, USEC_PER_MSEC));
+                        size = strpcpyf(&p, size, "%s (loader) + ", FORMAT_TIMESPAN(loader_usec, USEC_PER_MSEC));
 
                 if (dual_timestamp_is_set(&m->timestamps[MANAGER_TIMESTAMP_INITRD])) {
 
@@ -3945,10 +3448,10 @@ static void manager_notify_finished(Manager *m) {
                                    "USERSPACE_USEC="USEC_FMT, userspace_usec,
                                    LOG_MESSAGE("Startup finished in %s%s (kernel) + %s (initrd) + %s (userspace) = %s.",
                                                buf,
-                                               format_timespan(kernel, sizeof(kernel), kernel_usec, USEC_PER_MSEC),
-                                               format_timespan(initrd, sizeof(initrd), initrd_usec, USEC_PER_MSEC),
-                                               format_timespan(userspace, sizeof(userspace), userspace_usec, USEC_PER_MSEC),
-                                               format_timespan(sum, sizeof(sum), total_usec, USEC_PER_MSEC)));
+                                               FORMAT_TIMESPAN(kernel_usec, USEC_PER_MSEC),
+                                               FORMAT_TIMESPAN(initrd_usec, USEC_PER_MSEC),
+                                               FORMAT_TIMESPAN(userspace_usec, USEC_PER_MSEC),
+                                               FORMAT_TIMESPAN(total_usec, USEC_PER_MSEC)));
                 } else {
                         /* The initrd-less case on bare-metal */
 
@@ -3961,9 +3464,9 @@ static void manager_notify_finished(Manager *m) {
                                    "USERSPACE_USEC="USEC_FMT, userspace_usec,
                                    LOG_MESSAGE("Startup finished in %s%s (kernel) + %s (userspace) = %s.",
                                                buf,
-                                               format_timespan(kernel, sizeof(kernel), kernel_usec, USEC_PER_MSEC),
-                                               format_timespan(userspace, sizeof(userspace), userspace_usec, USEC_PER_MSEC),
-                                               format_timespan(sum, sizeof(sum), total_usec, USEC_PER_MSEC)));
+                                               FORMAT_TIMESPAN(kernel_usec, USEC_PER_MSEC),
+                                               FORMAT_TIMESPAN(userspace_usec, USEC_PER_MSEC),
+                                               FORMAT_TIMESPAN(total_usec, USEC_PER_MSEC)));
                 }
         } else {
                 /* The container and --user case */
@@ -3974,33 +3477,37 @@ static void manager_notify_finished(Manager *m) {
                            "MESSAGE_ID=" SD_MESSAGE_USER_STARTUP_FINISHED_STR,
                            "USERSPACE_USEC="USEC_FMT, userspace_usec,
                            LOG_MESSAGE("Startup finished in %s.",
-                                       format_timespan(sum, sizeof(sum), total_usec, USEC_PER_MSEC)));
+                                       FORMAT_TIMESPAN(total_usec, USEC_PER_MSEC)));
         }
 
         bus_manager_send_finished(m, firmware_usec, loader_usec, kernel_usec, initrd_usec, userspace_usec, total_usec);
 
-        sd_notifyf(false,
-                   m->ready_sent ? "STATUS=Startup finished in %s."
-                                 : "READY=1\n"
-                                   "STATUS=Startup finished in %s.",
-                   format_timespan(sum, sizeof(sum), total_usec, USEC_PER_MSEC));
-        m->ready_sent = true;
-
         log_taint_string(m);
 }
 
-static void manager_send_ready(Manager *m) {
+static void user_manager_send_ready(Manager *m) {
         assert(m);
 
         /* We send READY=1 on reaching basic.target only when running in --user mode. */
         if (!MANAGER_IS_USER(m) || m->ready_sent)
                 return;
 
-        m->ready_sent = true;
-
         sd_notifyf(false,
                    "READY=1\n"
                    "STATUS=Reached " SPECIAL_BASIC_TARGET ".");
+        m->ready_sent = true;
+        m->status_ready = false;
+}
+
+static void manager_send_ready(Manager *m) {
+        if (m->ready_sent && m->status_ready)
+                /* Skip the notification if nothing changed. */
+                return;
+
+        sd_notifyf(false,
+                   "%sSTATUS=Ready.",
+                   m->ready_sent ? "READY=1\n" : "");
+        m->ready_sent = m->status_ready = true;
 }
 
 static void manager_check_basic_target(Manager *m) {
@@ -4017,7 +3524,7 @@ static void manager_check_basic_target(Manager *m) {
                 return;
 
         /* For user managers, send out READY=1 as soon as we reach basic.target */
-        manager_send_ready(m);
+        user_manager_send_ready(m);
 
         /* Log the taint string as soon as we reach basic.target */
         log_taint_string(m);
@@ -4048,6 +3555,11 @@ void manager_check_finished(Manager *m) {
         if (hashmap_buckets(m->jobs) > hashmap_size(m->units) / 10)
                 m->jobs = hashmap_free(m->jobs);
 
+        manager_send_ready(m);
+
+        if (MANAGER_IS_FINISHED(m))
+                return;
+
         manager_flip_auto_status(m, false, "boot finished");
 
         /* Notify Type=idle units that we are done now */
@@ -4062,9 +3574,6 @@ void manager_check_finished(Manager *m) {
         /* This is no longer the first boot */
         manager_set_first_boot(m, false);
 
-        if (MANAGER_IS_FINISHED(m))
-                return;
-
         dual_timestamp_get(m->timestamps + MANAGER_TIMESTAMP_FINISH);
 
         manager_notify_finished(m);
@@ -4934,33 +4443,33 @@ ManagerTimestamp manager_timestamp_initrd_mangle(ManagerTimestamp s) {
 
 static const char *const manager_state_table[_MANAGER_STATE_MAX] = {
         [MANAGER_INITIALIZING] = "initializing",
-        [MANAGER_STARTING] = "starting",
-        [MANAGER_RUNNING] = "running",
-        [MANAGER_DEGRADED] = "degraded",
-        [MANAGER_MAINTENANCE] = "maintenance",
-        [MANAGER_STOPPING] = "stopping",
+        [MANAGER_STARTING]     = "starting",
+        [MANAGER_RUNNING]      = "running",
+        [MANAGER_DEGRADED]     = "degraded",
+        [MANAGER_MAINTENANCE]  = "maintenance",
+        [MANAGER_STOPPING]     = "stopping",
 };
 
 DEFINE_STRING_TABLE_LOOKUP(manager_state, ManagerState);
 
 static const char *const manager_timestamp_table[_MANAGER_TIMESTAMP_MAX] = {
-        [MANAGER_TIMESTAMP_FIRMWARE] = "firmware",
-        [MANAGER_TIMESTAMP_LOADER] = "loader",
-        [MANAGER_TIMESTAMP_KERNEL] = "kernel",
-        [MANAGER_TIMESTAMP_INITRD] = "initrd",
-        [MANAGER_TIMESTAMP_USERSPACE] = "userspace",
-        [MANAGER_TIMESTAMP_FINISH] = "finish",
-        [MANAGER_TIMESTAMP_SECURITY_START] = "security-start",
-        [MANAGER_TIMESTAMP_SECURITY_FINISH] = "security-finish",
-        [MANAGER_TIMESTAMP_GENERATORS_START] = "generators-start",
-        [MANAGER_TIMESTAMP_GENERATORS_FINISH] = "generators-finish",
-        [MANAGER_TIMESTAMP_UNITS_LOAD_START] = "units-load-start",
-        [MANAGER_TIMESTAMP_UNITS_LOAD_FINISH] = "units-load-finish",
-        [MANAGER_TIMESTAMP_INITRD_SECURITY_START] = "initrd-security-start",
-        [MANAGER_TIMESTAMP_INITRD_SECURITY_FINISH] = "initrd-security-finish",
-        [MANAGER_TIMESTAMP_INITRD_GENERATORS_START] = "initrd-generators-start",
+        [MANAGER_TIMESTAMP_FIRMWARE]                 = "firmware",
+        [MANAGER_TIMESTAMP_LOADER]                   = "loader",
+        [MANAGER_TIMESTAMP_KERNEL]                   = "kernel",
+        [MANAGER_TIMESTAMP_INITRD]                   = "initrd",
+        [MANAGER_TIMESTAMP_USERSPACE]                = "userspace",
+        [MANAGER_TIMESTAMP_FINISH]                   = "finish",
+        [MANAGER_TIMESTAMP_SECURITY_START]           = "security-start",
+        [MANAGER_TIMESTAMP_SECURITY_FINISH]          = "security-finish",
+        [MANAGER_TIMESTAMP_GENERATORS_START]         = "generators-start",
+        [MANAGER_TIMESTAMP_GENERATORS_FINISH]        = "generators-finish",
+        [MANAGER_TIMESTAMP_UNITS_LOAD_START]         = "units-load-start",
+        [MANAGER_TIMESTAMP_UNITS_LOAD_FINISH]        = "units-load-finish",
+        [MANAGER_TIMESTAMP_INITRD_SECURITY_START]    = "initrd-security-start",
+        [MANAGER_TIMESTAMP_INITRD_SECURITY_FINISH]   = "initrd-security-finish",
+        [MANAGER_TIMESTAMP_INITRD_GENERATORS_START]  = "initrd-generators-start",
         [MANAGER_TIMESTAMP_INITRD_GENERATORS_FINISH] = "initrd-generators-finish",
-        [MANAGER_TIMESTAMP_INITRD_UNITS_LOAD_START] = "initrd-units-load-start",
+        [MANAGER_TIMESTAMP_INITRD_UNITS_LOAD_START]  = "initrd-units-load-start",
         [MANAGER_TIMESTAMP_INITRD_UNITS_LOAD_FINISH] = "initrd-units-load-finish",
 };
 
@@ -4968,8 +4477,8 @@ DEFINE_STRING_TABLE_LOOKUP(manager_timestamp, ManagerTimestamp);
 
 static const char* const oom_policy_table[_OOM_POLICY_MAX] = {
         [OOM_CONTINUE] = "continue",
-        [OOM_STOP] = "stop",
-        [OOM_KILL] = "kill",
+        [OOM_STOP]     = "stop",
+        [OOM_KILL]     = "kill",
 };
 
 DEFINE_STRING_TABLE_LOOKUP(oom_policy, OOMPolicy);
index b3e7c68e6ddd0bff0021baee7dd8b111a15f59cf..284ea42a9dd43a5b989ac91131d942784f48a490 100644 (file)
@@ -329,6 +329,9 @@ struct Manager {
         /* Have we already sent out the READY=1 notification? */
         bool ready_sent;
 
+        /* Was the last status sent "STATUS=Ready."? */
+        bool status_ready;
+
         /* Have we already printed the taint line if necessary? */
         bool taint_logged;
 
@@ -500,12 +503,9 @@ int manager_set_default_rlimits(Manager *m, struct rlimit **default_rlimit);
 
 int manager_loop(Manager *m);
 
-int manager_open_serialization(Manager *m, FILE **_f);
-
-int manager_serialize(Manager *m, FILE *f, FDSet *fds, bool switching_root);
-int manager_deserialize(Manager *m, FILE *f, FDSet *fds);
-
 int manager_reload(Manager *m);
+Manager* manager_reloading_start(Manager *m);
+void manager_reloading_stopp(Manager **m);
 
 void manager_reset_failed(Manager *m);
 
index f0d2c6f642318132bf3ed0d17dfe7adb5251d58e..1941081972bf5ed172688549f87688594ba79a9d 100644 (file)
@@ -87,6 +87,8 @@ libcore_sources = '''
         locale-setup.h
         manager-dump.c
         manager-dump.h
+        manager-serialize.c
+        manager-serialize.h
         manager.c
         manager.h
         mount.c
@@ -208,9 +210,9 @@ meson.add_install_script('sh', '-c', mkdir_p.format(systemgeneratordir))
 meson.add_install_script('sh', '-c', mkdir_p.format(usergeneratordir))
 
 if install_sysconfdir
-        meson.add_install_script('sh', '-c', mkdir_p.format(join_paths(pkgsysconfdir, 'system')))
-        meson.add_install_script('sh', '-c', mkdir_p.format(join_paths(pkgsysconfdir, 'user')))
-        meson.add_install_script('sh', '-c', mkdir_p.format(join_paths(sysconfdir, 'xdg/systemd')))
+        meson.add_install_script('sh', '-c', mkdir_p.format(pkgsysconfdir / 'system'))
+        meson.add_install_script('sh', '-c', mkdir_p.format(pkgsysconfdir / 'user'))
+        meson.add_install_script('sh', '-c', mkdir_p.format(sysconfdir / 'xdg/systemd'))
 endif
 
 ############################################################
index 053deac14dbfafb835ebefa29dad6f47de3c1e1a..fb8f72e2576d1eb5f514dbce8093904b3eecd379 100644 (file)
@@ -770,7 +770,6 @@ static int mount_coldplug(Unit *u) {
 }
 
 static void mount_dump(Unit *u, FILE *f, const char *prefix) {
-        char buf[FORMAT_TIMESPAN_MAX];
         Mount *m = MOUNT(u);
         MountParameters *p;
 
@@ -811,7 +810,7 @@ static void mount_dump(Unit *u, FILE *f, const char *prefix) {
                 prefix, yes_no(m->lazy_unmount),
                 prefix, yes_no(m->force_unmount),
                 prefix, yes_no(m->read_write_only),
-                prefix, format_timespan(buf, sizeof(buf), m->timeout_usec, USEC_PER_SEC));
+                prefix, FORMAT_TIMESPAN(m->timeout_usec, USEC_PER_SEC));
 
         if (m->control_pid > 0)
                 fprintf(f,
@@ -1224,7 +1223,7 @@ static int mount_stop(Unit *u) {
                 return 0;
 
         default:
-                assert_not_reached("Unexpected state.");
+                assert_not_reached();
         }
 }
 
@@ -1384,7 +1383,7 @@ static void mount_sigchld_event(Unit *u, pid_t pid, int code, int status) {
         else if (code == CLD_DUMPED)
                 f = MOUNT_FAILURE_CORE_DUMP;
         else
-                assert_not_reached("Unknown code");
+                assert_not_reached();
 
         if (IN_SET(m->state, MOUNT_REMOUNTING, MOUNT_REMOUNTING_SIGKILL, MOUNT_REMOUNTING_SIGTERM))
                 mount_set_reload_result(m, f);
@@ -1466,7 +1465,7 @@ static void mount_sigchld_event(Unit *u, pid_t pid, int code, int status) {
                 break;
 
         default:
-                assert_not_reached("Uh, control process died at wrong time.");
+                assert_not_reached();
         }
 
         /* Notify clients about changed exit status */
@@ -1542,7 +1541,7 @@ static int mount_dispatch_timer(sd_event_source *source, usec_t usec, void *user
                 break;
 
         default:
-                assert_not_reached("Timeout at wrong time.");
+                assert_not_reached();
         }
 
         return 0;
@@ -2140,7 +2139,7 @@ static int mount_can_clean(Unit *u, ExecCleanMask *ret) {
 }
 
 static const char* const mount_exec_command_table[_MOUNT_EXEC_COMMAND_MAX] = {
-        [MOUNT_EXEC_MOUNT] = "ExecMount",
+        [MOUNT_EXEC_MOUNT]   = "ExecMount",
         [MOUNT_EXEC_UNMOUNT] = "ExecUnmount",
         [MOUNT_EXEC_REMOUNT] = "ExecRemount",
 };
@@ -2148,14 +2147,14 @@ static const char* const mount_exec_command_table[_MOUNT_EXEC_COMMAND_MAX] = {
 DEFINE_STRING_TABLE_LOOKUP(mount_exec_command, MountExecCommand);
 
 static const char* const mount_result_table[_MOUNT_RESULT_MAX] = {
-        [MOUNT_SUCCESS] = "success",
-        [MOUNT_FAILURE_RESOURCES] = "resources",
-        [MOUNT_FAILURE_TIMEOUT] = "timeout",
-        [MOUNT_FAILURE_EXIT_CODE] = "exit-code",
-        [MOUNT_FAILURE_SIGNAL] = "signal",
-        [MOUNT_FAILURE_CORE_DUMP] = "core-dump",
+        [MOUNT_SUCCESS]                 = "success",
+        [MOUNT_FAILURE_RESOURCES]       = "resources",
+        [MOUNT_FAILURE_TIMEOUT]         = "timeout",
+        [MOUNT_FAILURE_EXIT_CODE]       = "exit-code",
+        [MOUNT_FAILURE_SIGNAL]          = "signal",
+        [MOUNT_FAILURE_CORE_DUMP]       = "core-dump",
         [MOUNT_FAILURE_START_LIMIT_HIT] = "start-limit-hit",
-        [MOUNT_FAILURE_PROTOCOL] = "protocol",
+        [MOUNT_FAILURE_PROTOCOL]        = "protocol",
 };
 
 DEFINE_STRING_TABLE_LOOKUP(mount_result, MountResult);
index 982aeeac1915b002cbc93badaf3020dab267ffb2..e302e948484c7fa4866c1f5f81c02b4b05bf83ec 100644 (file)
@@ -570,7 +570,7 @@ static int append_protect_home(MountEntry **p, ProtectHome protect_home, bool ig
                 return append_static_mounts(p, protect_home_yes_table, ELEMENTSOF(protect_home_yes_table), ignore_protect);
 
         default:
-                assert_not_reached("Unexpected ProtectHome= value");
+                assert_not_reached();
         }
 }
 
@@ -592,7 +592,7 @@ static int append_protect_system(MountEntry **p, ProtectSystem protect_system, b
                 return append_static_mounts(p, protect_system_full_table, ELEMENTSOF(protect_system_full_table), ignore_protect);
 
         default:
-                assert_not_reached("Unexpected ProtectSystem= value");
+                assert_not_reached();
         }
 }
 
@@ -1359,7 +1359,7 @@ static int apply_one_mount(
                 return mount_overlay(m);
 
         default:
-                assert_not_reached("Unknown mode");
+                assert_not_reached();
         }
 
         assert(what);
index e098e83a311ce0ddcedec580056b93efa1ea2a2a..800524a3089b9565ca632b69eb3e38d058e1940a 100644 (file)
@@ -674,13 +674,14 @@ static int path_deserialize_item(Unit *u, const char *key, const char *value, FD
                         p->result = f;
 
         } else if (streq(key, "path-spec")) {
-                int previous_exists, skip = 0, r;
+                int previous_exists, skip = 0;
                 _cleanup_free_ char *type_str = NULL;
 
                 if (sscanf(value, "%ms %i %n", &type_str, &previous_exists, &skip) < 2)
                         log_unit_debug(u, "Failed to parse path-spec value: %s", value);
                 else {
                         _cleanup_free_ char *unescaped = NULL;
+                        ssize_t l;
                         PathType type;
                         PathSpec *s;
 
@@ -690,9 +691,9 @@ static int path_deserialize_item(Unit *u, const char *key, const char *value, FD
                                 return 0;
                         }
 
-                        r = cunescape(value+skip, 0, &unescaped);
-                        if (r < 0) {
-                                log_unit_warning_errno(u, r, "Failed to unescape serialize path: %m");
+                        l = cunescape(value+skip, 0, &unescaped);
+                        if (l < 0) {
+                                log_unit_warning_errno(u, l, "Failed to unescape serialize path: %m");
                                 return 0;
                         }
 
@@ -812,19 +813,19 @@ static void path_reset_failed(Unit *u) {
 }
 
 static const char* const path_type_table[_PATH_TYPE_MAX] = {
-        [PATH_EXISTS] = "PathExists",
-        [PATH_EXISTS_GLOB] = "PathExistsGlob",
+        [PATH_EXISTS]              = "PathExists",
+        [PATH_EXISTS_GLOB]         = "PathExistsGlob",
         [PATH_DIRECTORY_NOT_EMPTY] = "DirectoryNotEmpty",
-        [PATH_CHANGED] = "PathChanged",
-        [PATH_MODIFIED] = "PathModified",
+        [PATH_CHANGED]             = "PathChanged",
+        [PATH_MODIFIED]            = "PathModified",
 };
 
 DEFINE_STRING_TABLE_LOOKUP(path_type, PathType);
 
 static const char* const path_result_table[_PATH_RESULT_MAX] = {
-        [PATH_SUCCESS] = "success",
-        [PATH_FAILURE_RESOURCES] = "resources",
-        [PATH_FAILURE_START_LIMIT_HIT] = "start-limit-hit",
+        [PATH_SUCCESS]                      = "success",
+        [PATH_FAILURE_RESOURCES]            = "resources",
+        [PATH_FAILURE_START_LIMIT_HIT]      = "start-limit-hit",
         [PATH_FAILURE_UNIT_START_LIMIT_HIT] = "unit-start-limit-hit",
 };
 
index af6311bb5f6c1a1b7626957e953983c0d385a2d3..560a7d9f3eed2b7ee8714ef06163d7e080ff569b 100644 (file)
@@ -255,7 +255,6 @@ static int scope_coldplug(Unit *u) {
 
 static void scope_dump(Unit *u, FILE *f, const char *prefix) {
         Scope *s = SCOPE(u);
-        char buf_runtime[FORMAT_TIMESPAN_MAX];
 
         assert(s);
         assert(f);
@@ -266,7 +265,7 @@ static void scope_dump(Unit *u, FILE *f, const char *prefix) {
                 "%sRuntimeMaxSec: %s\n",
                 prefix, scope_state_to_string(s->state),
                 prefix, scope_result_to_string(s->result),
-                prefix, format_timespan(buf_runtime, sizeof(buf_runtime), s->runtime_max_usec, USEC_PER_SEC));
+                prefix, FORMAT_TIMESPAN(s->runtime_max_usec, USEC_PER_SEC));
 
         cgroup_context_dump(UNIT(s), f, prefix);
         kill_context_dump(&s->kill_context, f, prefix);
@@ -563,7 +562,7 @@ static int scope_dispatch_timer(sd_event_source *source, usec_t usec, void *user
                 break;
 
         default:
-                assert_not_reached("Timeout at wrong time.");
+                assert_not_reached();
         }
 
         return 0;
@@ -633,9 +632,9 @@ static void scope_enumerate_perpetual(Manager *m) {
 }
 
 static const char* const scope_result_table[_SCOPE_RESULT_MAX] = {
-        [SCOPE_SUCCESS] = "success",
+        [SCOPE_SUCCESS]           = "success",
         [SCOPE_FAILURE_RESOURCES] = "resources",
-        [SCOPE_FAILURE_TIMEOUT] = "timeout",
+        [SCOPE_FAILURE_TIMEOUT]   = "timeout",
 };
 
 DEFINE_STRING_TABLE_LOOKUP(scope_result, ScopeResult);
index 2bafbee3eb6a18f13fb7c89172a742b3fc71af60..3f873baa9101c726d56ffb45d845c708b8193b12 100644 (file)
@@ -64,7 +64,6 @@ int mac_selinux_setup(bool *loaded_policy) {
         r = selinux_init_load_policy(&enforce);
         if (r == 0) {
                 _cleanup_(mac_selinux_freep) char *label = NULL;
-                char timespan[FORMAT_TIMESPAN_MAX];
 
                 mac_selinux_retest();
 
@@ -84,7 +83,7 @@ int mac_selinux_setup(bool *loaded_policy) {
                 after_load = now(CLOCK_MONOTONIC);
 
                 log_info("Successfully loaded SELinux policy in %s.",
-                         format_timespan(timespan, sizeof(timespan), after_load - before_load, 0));
+                         FORMAT_TIMESPAN(after_load - before_load, 0));
 
                 *loaded_policy = true;
 
index cb0a528f0d62b23175e430d67fa710ade81a666c..ddcfeb8523f539083970ab50d9aee1dbaedd31a1 100644 (file)
@@ -768,8 +768,6 @@ static int service_load(Unit *u) {
 }
 
 static void service_dump(Unit *u, FILE *f, const char *prefix) {
-        char buf_restart[FORMAT_TIMESPAN_MAX], buf_start[FORMAT_TIMESPAN_MAX], buf_stop[FORMAT_TIMESPAN_MAX],
-                buf_runtime[FORMAT_TIMESPAN_MAX], buf_watchdog[FORMAT_TIMESPAN_MAX], buf_abort[FORMAT_TIMESPAN_MAX];
         ServiceExecCommand c;
         Service *s = SERVICE(u);
         const char *prefix2;
@@ -844,22 +842,22 @@ static void service_dump(Unit *u, FILE *f, const char *prefix) {
                 "%sTimeoutStopSec: %s\n"
                 "%sTimeoutStartFailureMode: %s\n"
                 "%sTimeoutStopFailureMode: %s\n",
-                prefix, format_timespan(buf_restart, sizeof(buf_restart), s->restart_usec, USEC_PER_SEC),
-                prefix, format_timespan(buf_start, sizeof(buf_start), s->timeout_start_usec, USEC_PER_SEC),
-                prefix, format_timespan(buf_stop, sizeof(buf_stop), s->timeout_stop_usec, USEC_PER_SEC),
+                prefix, FORMAT_TIMESPAN(s->restart_usec, USEC_PER_SEC),
+                prefix, FORMAT_TIMESPAN(s->timeout_start_usec, USEC_PER_SEC),
+                prefix, FORMAT_TIMESPAN(s->timeout_stop_usec, USEC_PER_SEC),
                 prefix, service_timeout_failure_mode_to_string(s->timeout_start_failure_mode),
                 prefix, service_timeout_failure_mode_to_string(s->timeout_stop_failure_mode));
 
         if (s->timeout_abort_set)
                 fprintf(f,
                         "%sTimeoutAbortSec: %s\n",
-                        prefix, format_timespan(buf_abort, sizeof(buf_abort), s->timeout_abort_usec, USEC_PER_SEC));
+                        prefix, FORMAT_TIMESPAN(s->timeout_abort_usec, USEC_PER_SEC));
 
         fprintf(f,
                 "%sRuntimeMaxSec: %s\n"
                 "%sWatchdogSec: %s\n",
-                prefix, format_timespan(buf_runtime, sizeof(buf_runtime), s->runtime_max_usec, USEC_PER_SEC),
-                prefix, format_timespan(buf_watchdog, sizeof(buf_watchdog), s->watchdog_usec, USEC_PER_SEC));
+                prefix, FORMAT_TIMESPAN(s->runtime_max_usec, USEC_PER_SEC),
+                prefix, FORMAT_TIMESPAN(s->watchdog_usec, USEC_PER_SEC));
 
         kill_context_dump(&s->kill_context, f, prefix);
         exec_context_dump(&s->exec_context, f, prefix);
@@ -1685,7 +1683,7 @@ static bool service_shall_restart(Service *s, const char **reason) {
                 return IN_SET(s->result, SERVICE_FAILURE_SIGNAL, SERVICE_FAILURE_CORE_DUMP);
 
         default:
-                assert_not_reached("unknown restart setting");
+                assert_not_reached();
         }
 }
 
@@ -2159,7 +2157,7 @@ static void service_enter_start(Service *s) {
                 service_set_main_pid(s, pid);
                 service_set_state(s, SERVICE_START);
         } else
-                assert_not_reached("Unknown service type");
+                assert_not_reached();
 
         return;
 
@@ -2782,7 +2780,7 @@ int service_deserialize_exec_command(
                                 return -ENOMEM;
                         break;
                 default:
-                        assert_not_reached("Logic error in exec command deserialization");
+                        assert_not_reached();
                 }
         }
 
@@ -2890,10 +2888,11 @@ static int service_deserialize_item(Unit *u, const char *key, const char *value,
                         log_unit_error_errno(u, r, "Unable to deserialize current bus owner %s: %m", value);
         } else if (streq(key, "status-text")) {
                 char *t;
+                ssize_t l;
 
-                r = cunescape(value, 0, &t);
-                if (r < 0)
-                        log_unit_debug_errno(u, r, "Failed to unescape status text '%s': %m", value);
+                l = cunescape(value, 0, &t);
+                if (l < 0)
+                        log_unit_debug_errno(u, l, "Failed to unescape status text '%s': %m", value);
                 else
                         free_and_replace(s->status_text, t);
 
@@ -3393,7 +3392,7 @@ static void service_sigchld_event(Unit *u, pid_t pid, int code, int status) {
         else if (code == CLD_DUMPED)
                 f = SERVICE_FAILURE_CORE_DUMP;
         else
-                assert_not_reached("Unknown code");
+                assert_not_reached();
 
         if (s->main_pid == pid) {
                 /* Clean up the exec_fd event source. We want to do this here, not later in
@@ -3524,7 +3523,7 @@ static void service_sigchld_event(Unit *u, pid_t pid, int code, int status) {
                                 break;
 
                         default:
-                                assert_not_reached("Uh, main process died at wrong time.");
+                                assert_not_reached();
                         }
                 }
 
@@ -3702,7 +3701,7 @@ static void service_sigchld_event(Unit *u, pid_t pid, int code, int status) {
                                 break;
 
                         default:
-                                assert_not_reached("Uh, control process died at wrong time.");
+                                assert_not_reached();
                         }
                 }
         } else /* Neither control nor main PID? If so, don't notify about anything */
@@ -3757,7 +3756,7 @@ static int service_dispatch_timer(sd_event_source *source, usec_t usec, void *us
                         break;
 
                 default:
-                        assert_not_reached("unknown timeout mode");
+                        assert_not_reached();
                 }
                 break;
 
@@ -3797,7 +3796,7 @@ static int service_dispatch_timer(sd_event_source *source, usec_t usec, void *us
                         break;
 
                 default:
-                        assert_not_reached("unknown timeout mode");
+                        assert_not_reached();
                 }
                 break;
 
@@ -3858,7 +3857,7 @@ static int service_dispatch_timer(sd_event_source *source, usec_t usec, void *us
                         break;
 
                 default:
-                        assert_not_reached("unknown timeout mode");
+                        assert_not_reached();
                 }
                 break;
 
@@ -3892,12 +3891,11 @@ static int service_dispatch_timer(sd_event_source *source, usec_t usec, void *us
                 break;
 
         case SERVICE_AUTO_RESTART:
-                if (s->restart_usec > 0) {
-                        char buf_restart[FORMAT_TIMESPAN_MAX];
+                if (s->restart_usec > 0)
                         log_unit_debug(UNIT(s),
                                        "Service RestartSec=%s expired, scheduling restart.",
-                                       format_timespan(buf_restart, sizeof buf_restart, s->restart_usec, USEC_PER_SEC));
-                else
+                                       FORMAT_TIMESPAN(s->restart_usec, USEC_PER_SEC));
+                else
                         log_unit_debug(UNIT(s),
                                        "Service has no hold-off time (RestartSec=0), scheduling restart.");
 
@@ -3914,7 +3912,7 @@ static int service_dispatch_timer(sd_event_source *source, usec_t usec, void *us
                 break;
 
         default:
-                assert_not_reached("Timeout at wrong time.");
+                assert_not_reached();
         }
 
         return 0;
@@ -3922,7 +3920,6 @@ static int service_dispatch_timer(sd_event_source *source, usec_t usec, void *us
 
 static int service_dispatch_watchdog(sd_event_source *source, usec_t usec, void *userdata) {
         Service *s = SERVICE(userdata);
-        char t[FORMAT_TIMESPAN_MAX];
         usec_t watchdog_usec;
 
         assert(s);
@@ -3932,12 +3929,12 @@ static int service_dispatch_watchdog(sd_event_source *source, usec_t usec, void
 
         if (UNIT(s)->manager->service_watchdogs) {
                 log_unit_error(UNIT(s), "Watchdog timeout (limit %s)!",
-                               format_timespan(t, sizeof(t), watchdog_usec, 1));
+                               FORMAT_TIMESPAN(watchdog_usec, 1));
 
                 service_enter_signal(s, SERVICE_STOP_WATCHDOG, SERVICE_FAILURE_WATCHDOG);
         } else
                 log_unit_warning(UNIT(s), "Watchdog disabled! Ignoring watchdog timeout (limit %s)!",
-                                 format_timespan(t, sizeof(t), watchdog_usec, 1));
+                                 FORMAT_TIMESPAN(watchdog_usec, 1));
 
         return 0;
 }
@@ -4382,6 +4379,14 @@ static int service_exit_status(Unit *u) {
         return s->main_exec_status.status;
 }
 
+static const char* service_status_text(Unit *u) {
+        Service *s = SERVICE(u);
+
+        assert(s);
+
+        return s->status_text;
+}
+
 static int service_clean(Unit *u, ExecCleanMask mask) {
         _cleanup_strv_free_ char **l = NULL;
         Service *s = SERVICE(u);
@@ -4443,82 +4448,82 @@ static const char *service_finished_job(Unit *u, JobType t, JobResult result) {
 }
 
 static const char* const service_restart_table[_SERVICE_RESTART_MAX] = {
-        [SERVICE_RESTART_NO] = "no",
-        [SERVICE_RESTART_ON_SUCCESS] = "on-success",
-        [SERVICE_RESTART_ON_FAILURE] = "on-failure",
+        [SERVICE_RESTART_NO]          = "no",
+        [SERVICE_RESTART_ON_SUCCESS]  = "on-success",
+        [SERVICE_RESTART_ON_FAILURE]  = "on-failure",
         [SERVICE_RESTART_ON_ABNORMAL] = "on-abnormal",
         [SERVICE_RESTART_ON_WATCHDOG] = "on-watchdog",
-        [SERVICE_RESTART_ON_ABORT] = "on-abort",
-        [SERVICE_RESTART_ALWAYS] = "always",
+        [SERVICE_RESTART_ON_ABORT]    = "on-abort",
+        [SERVICE_RESTART_ALWAYS]      = "always",
 };
 
 DEFINE_STRING_TABLE_LOOKUP(service_restart, ServiceRestart);
 
 static const char* const service_type_table[_SERVICE_TYPE_MAX] = {
-        [SERVICE_SIMPLE] = "simple",
+        [SERVICE_SIMPLE]  = "simple",
         [SERVICE_FORKING] = "forking",
         [SERVICE_ONESHOT] = "oneshot",
-        [SERVICE_DBUS] = "dbus",
-        [SERVICE_NOTIFY] = "notify",
-        [SERVICE_IDLE] = "idle",
-        [SERVICE_EXEC] = "exec",
+        [SERVICE_DBUS]    = "dbus",
+        [SERVICE_NOTIFY]  = "notify",
+        [SERVICE_IDLE]    = "idle",
+        [SERVICE_EXEC]    = "exec",
 };
 
 DEFINE_STRING_TABLE_LOOKUP(service_type, ServiceType);
 
 static const char* const service_exec_command_table[_SERVICE_EXEC_COMMAND_MAX] = {
-        [SERVICE_EXEC_CONDITION] = "ExecCondition",
-        [SERVICE_EXEC_START_PRE] = "ExecStartPre",
-        [SERVICE_EXEC_START] = "ExecStart",
+        [SERVICE_EXEC_CONDITION]  = "ExecCondition",
+        [SERVICE_EXEC_START_PRE]  = "ExecStartPre",
+        [SERVICE_EXEC_START]      = "ExecStart",
         [SERVICE_EXEC_START_POST] = "ExecStartPost",
-        [SERVICE_EXEC_RELOAD] = "ExecReload",
-        [SERVICE_EXEC_STOP] = "ExecStop",
-        [SERVICE_EXEC_STOP_POST] = "ExecStopPost",
+        [SERVICE_EXEC_RELOAD]     = "ExecReload",
+        [SERVICE_EXEC_STOP]       = "ExecStop",
+        [SERVICE_EXEC_STOP_POST]  = "ExecStopPost",
 };
 
 DEFINE_STRING_TABLE_LOOKUP(service_exec_command, ServiceExecCommand);
 
 static const char* const service_exec_ex_command_table[_SERVICE_EXEC_COMMAND_MAX] = {
-        [SERVICE_EXEC_CONDITION] = "ExecConditionEx",
-        [SERVICE_EXEC_START_PRE] = "ExecStartPreEx",
-        [SERVICE_EXEC_START] = "ExecStartEx",
+        [SERVICE_EXEC_CONDITION]  = "ExecConditionEx",
+        [SERVICE_EXEC_START_PRE]  = "ExecStartPreEx",
+        [SERVICE_EXEC_START]      = "ExecStartEx",
         [SERVICE_EXEC_START_POST] = "ExecStartPostEx",
-        [SERVICE_EXEC_RELOAD] = "ExecReloadEx",
-        [SERVICE_EXEC_STOP] = "ExecStopEx",
-        [SERVICE_EXEC_STOP_POST] = "ExecStopPostEx",
+        [SERVICE_EXEC_RELOAD]     = "ExecReloadEx",
+        [SERVICE_EXEC_STOP]       = "ExecStopEx",
+        [SERVICE_EXEC_STOP_POST]  = "ExecStopPostEx",
 };
 
 DEFINE_STRING_TABLE_LOOKUP(service_exec_ex_command, ServiceExecCommand);
 
 static const char* const notify_state_table[_NOTIFY_STATE_MAX] = {
-        [NOTIFY_UNKNOWN] = "unknown",
-        [NOTIFY_READY] = "ready",
+        [NOTIFY_UNKNOWN]   = "unknown",
+        [NOTIFY_READY]     = "ready",
         [NOTIFY_RELOADING] = "reloading",
-        [NOTIFY_STOPPING] = "stopping",
+        [NOTIFY_STOPPING]  = "stopping",
 };
 
 DEFINE_STRING_TABLE_LOOKUP(notify_state, NotifyState);
 
 static const char* const service_result_table[_SERVICE_RESULT_MAX] = {
-        [SERVICE_SUCCESS] = "success",
-        [SERVICE_FAILURE_RESOURCES] = "resources",
-        [SERVICE_FAILURE_PROTOCOL] = "protocol",
-        [SERVICE_FAILURE_TIMEOUT] = "timeout",
-        [SERVICE_FAILURE_EXIT_CODE] = "exit-code",
-        [SERVICE_FAILURE_SIGNAL] = "signal",
-        [SERVICE_FAILURE_CORE_DUMP] = "core-dump",
-        [SERVICE_FAILURE_WATCHDOG] = "watchdog",
+        [SERVICE_SUCCESS]                 = "success",
+        [SERVICE_FAILURE_RESOURCES]       = "resources",
+        [SERVICE_FAILURE_PROTOCOL]        = "protocol",
+        [SERVICE_FAILURE_TIMEOUT]         = "timeout",
+        [SERVICE_FAILURE_EXIT_CODE]       = "exit-code",
+        [SERVICE_FAILURE_SIGNAL]          = "signal",
+        [SERVICE_FAILURE_CORE_DUMP]       = "core-dump",
+        [SERVICE_FAILURE_WATCHDOG]        = "watchdog",
         [SERVICE_FAILURE_START_LIMIT_HIT] = "start-limit-hit",
-        [SERVICE_FAILURE_OOM_KILL] = "oom-kill",
-        [SERVICE_SKIP_CONDITION] = "exec-condition",
+        [SERVICE_FAILURE_OOM_KILL]        = "oom-kill",
+        [SERVICE_SKIP_CONDITION]          = "exec-condition",
 };
 
 DEFINE_STRING_TABLE_LOOKUP(service_result, ServiceResult);
 
 static const char* const service_timeout_failure_mode_table[_SERVICE_TIMEOUT_FAILURE_MODE_MAX] = {
         [SERVICE_TIMEOUT_TERMINATE] = "terminate",
-        [SERVICE_TIMEOUT_ABORT] = "abort",
-        [SERVICE_TIMEOUT_KILL] = "kill",
+        [SERVICE_TIMEOUT_ABORT]     = "abort",
+        [SERVICE_TIMEOUT_KILL]      = "kill",
 };
 
 DEFINE_STRING_TABLE_LOOKUP(service_timeout_failure_mode, ServiceTimeoutFailureMode);
@@ -4593,6 +4598,7 @@ const UnitVTable service_vtable = {
         .get_timeout = service_get_timeout,
         .needs_console = service_needs_console,
         .exit_status = service_exit_status,
+        .status_text = service_status_text,
 
         .status_message_formats = {
                 .finished_start_job = {
index 8144780bf83a2ee29d0074d1f297ceeb4c23ea52..675ad3c025038aac9e51a2160991bc07984d6cdb 100644 (file)
@@ -433,7 +433,7 @@ static void peer_address_hash_func(const SocketPeer *s, struct siphash *state) {
         else if (s->peer.sa.sa_family == AF_VSOCK)
                 siphash24_compress(&s->peer.vm.svm_cid, sizeof(s->peer.vm.svm_cid), state);
         else
-                assert_not_reached("Unknown address family.");
+                assert_not_reached();
 }
 
 static int peer_address_compare_func(const SocketPeer *x, const SocketPeer *y) {
@@ -451,7 +451,7 @@ static int peer_address_compare_func(const SocketPeer *x, const SocketPeer *y) {
         case AF_VSOCK:
                 return CMP(x->peer.vm.svm_cid, y->peer.vm.svm_cid);
         }
-        assert_not_reached("Black sheep in the family!");
+        assert_not_reached();
 }
 
 DEFINE_PRIVATE_HASH_OPS(peer_address_hash_ops, SocketPeer, peer_address_hash_func, peer_address_compare_func);
@@ -558,13 +558,11 @@ _const_ static const char* listen_lookup(int family, int type) {
         else if (type == SOCK_SEQPACKET)
                 return "ListenSequentialPacket";
 
-        assert_not_reached("Unknown socket type");
+        assert_not_reached();
         return NULL;
 }
 
 static void socket_dump(Unit *u, FILE *f, const char *prefix) {
-        char time_string[FORMAT_TIMESPAN_MAX];
-        SocketExecCommand c;
         Socket *s = SOCKET(u);
         SocketPort *p;
         const char *prefix2, *str;
@@ -723,12 +721,12 @@ static void socket_dump(Unit *u, FILE *f, const char *prefix) {
         if (s->keep_alive_time > 0)
                 fprintf(f,
                         "%sKeepAliveTimeSec: %s\n",
-                        prefix, format_timespan(time_string, FORMAT_TIMESPAN_MAX, s->keep_alive_time, USEC_PER_SEC));
+                        prefix, FORMAT_TIMESPAN(s->keep_alive_time, USEC_PER_SEC));
 
         if (s->keep_alive_interval > 0)
                 fprintf(f,
                         "%sKeepAliveIntervalSec: %s\n",
-                        prefix, format_timespan(time_string, FORMAT_TIMESPAN_MAX, s->keep_alive_interval, USEC_PER_SEC));
+                        prefix, FORMAT_TIMESPAN(s->keep_alive_interval, USEC_PER_SEC));
 
         if (s->keep_alive_cnt > 0)
                 fprintf(f,
@@ -738,7 +736,7 @@ static void socket_dump(Unit *u, FILE *f, const char *prefix) {
         if (s->defer_accept > 0)
                 fprintf(f,
                         "%sDeferAcceptSec: %s\n",
-                        prefix, format_timespan(time_string, FORMAT_TIMESPAN_MAX, s->defer_accept, USEC_PER_SEC));
+                        prefix, FORMAT_TIMESPAN(s->defer_accept, USEC_PER_SEC));
 
         LIST_FOREACH(port, p, s->ports) {
 
@@ -774,7 +772,7 @@ static void socket_dump(Unit *u, FILE *f, const char *prefix) {
         fprintf(f,
                 "%sTriggerLimitIntervalSec: %s\n"
                 "%sTriggerLimitBurst: %u\n",
-                prefix, format_timespan(time_string, FORMAT_TIMESPAN_MAX, s->trigger_limit.interval, USEC_PER_SEC),
+                prefix, FORMAT_TIMESPAN(s->trigger_limit.interval, USEC_PER_SEC),
                 prefix, s->trigger_limit.burst);
 
         str = ip_protocol_to_name(s->socket_protocol);
@@ -793,12 +791,12 @@ static void socket_dump(Unit *u, FILE *f, const char *prefix) {
 
         fprintf(f,
                 "%sTimeoutSec: %s\n",
-                prefix, format_timespan(time_string, FORMAT_TIMESPAN_MAX, s->timeout_usec, USEC_PER_SEC));
+                prefix, FORMAT_TIMESPAN(s->timeout_usec, USEC_PER_SEC));
 
         exec_context_dump(&s->exec_context, f, prefix);
         kill_context_dump(&s->kill_context, f, prefix);
 
-        for (c = 0; c < _SOCKET_EXEC_COMMAND_MAX; c++) {
+        for (SocketExecCommand c = 0; c < _SOCKET_EXEC_COMMAND_MAX; c++) {
                 if (!s->exec_command[c])
                         continue;
 
@@ -916,7 +914,7 @@ static int instance_from_socket(int fd, unsigned nr, char **instance) {
                 break;
 
         default:
-                assert_not_reached("Unhandled socket type.");
+                assert_not_reached();
         }
 
         *instance = r;
@@ -1726,7 +1724,7 @@ static int socket_open_fds(Socket *orig_s) {
                         break;
                 }
                 default:
-                        assert_not_reached("Unknown port type");
+                        assert_not_reached();
                 }
         }
 
@@ -3073,7 +3071,7 @@ static void socket_sigchld_event(Unit *u, pid_t pid, int code, int status) {
         else if (code == CLD_DUMPED)
                 f = SOCKET_FAILURE_CORE_DUMP;
         else
-                assert_not_reached("Unknown sigchld code");
+                assert_not_reached();
 
         if (s->control_command) {
                 exec_status_exit(&s->control_command->exec_status, &s->exec_context, pid, code, status);
@@ -3151,7 +3149,7 @@ static void socket_sigchld_event(Unit *u, pid_t pid, int code, int status) {
                         break;
 
                 default:
-                        assert_not_reached("Uh, control process died at wrong time.");
+                        assert_not_reached();
                 }
         }
 
@@ -3228,7 +3226,7 @@ static int socket_dispatch_timer(sd_event_source *source, usec_t usec, void *use
                 break;
 
         default:
-                assert_not_reached("Timeout at wrong time.");
+                assert_not_reached();
         }
 
         return 0;
@@ -3260,11 +3258,9 @@ int socket_collect_fds(Socket *s, int **fds) {
                 return -ENOMEM;
 
         LIST_FOREACH(port, p, s->ports) {
-                size_t i;
-
                 if (p->fd >= 0)
                         rfds[k++] = p->fd;
-                for (i = 0; i < p->n_auxiliary_fds; ++i)
+                for (size_t i = 0; i < p->n_auxiliary_fds; ++i)
                         rfds[k++] = p->auxiliary_fds[i];
         }
 
@@ -3429,24 +3425,24 @@ static int socket_can_clean(Unit *u, ExecCleanMask *ret) {
 }
 
 static const char* const socket_exec_command_table[_SOCKET_EXEC_COMMAND_MAX] = {
-        [SOCKET_EXEC_START_PRE] = "ExecStartPre",
+        [SOCKET_EXEC_START_PRE]   = "ExecStartPre",
         [SOCKET_EXEC_START_CHOWN] = "ExecStartChown",
-        [SOCKET_EXEC_START_POST] = "ExecStartPost",
-        [SOCKET_EXEC_STOP_PRE] = "ExecStopPre",
-        [SOCKET_EXEC_STOP_POST] = "ExecStopPost"
+        [SOCKET_EXEC_START_POST]  = "ExecStartPost",
+        [SOCKET_EXEC_STOP_PRE]    = "ExecStopPre",
+        [SOCKET_EXEC_STOP_POST]   = "ExecStopPost"
 };
 
 DEFINE_STRING_TABLE_LOOKUP(socket_exec_command, SocketExecCommand);
 
 static const char* const socket_result_table[_SOCKET_RESULT_MAX] = {
-        [SOCKET_SUCCESS] = "success",
-        [SOCKET_FAILURE_RESOURCES] = "resources",
-        [SOCKET_FAILURE_TIMEOUT] = "timeout",
-        [SOCKET_FAILURE_EXIT_CODE] = "exit-code",
-        [SOCKET_FAILURE_SIGNAL] = "signal",
-        [SOCKET_FAILURE_CORE_DUMP] = "core-dump",
-        [SOCKET_FAILURE_START_LIMIT_HIT] = "start-limit-hit",
-        [SOCKET_FAILURE_TRIGGER_LIMIT_HIT] = "trigger-limit-hit",
+        [SOCKET_SUCCESS]                         = "success",
+        [SOCKET_FAILURE_RESOURCES]               = "resources",
+        [SOCKET_FAILURE_TIMEOUT]                 = "timeout",
+        [SOCKET_FAILURE_EXIT_CODE]               = "exit-code",
+        [SOCKET_FAILURE_SIGNAL]                  = "signal",
+        [SOCKET_FAILURE_CORE_DUMP]               = "core-dump",
+        [SOCKET_FAILURE_START_LIMIT_HIT]         = "start-limit-hit",
+        [SOCKET_FAILURE_TRIGGER_LIMIT_HIT]       = "trigger-limit-hit",
         [SOCKET_FAILURE_SERVICE_START_LIMIT_HIT] = "service-start-limit-hit"
 };
 
@@ -3454,8 +3450,8 @@ DEFINE_STRING_TABLE_LOOKUP(socket_result, SocketResult);
 
 static const char* const socket_timestamping_table[_SOCKET_TIMESTAMPING_MAX] = {
         [SOCKET_TIMESTAMPING_OFF] = "off",
-        [SOCKET_TIMESTAMPING_US] = "us",
-        [SOCKET_TIMESTAMPING_NS] = "ns",
+        [SOCKET_TIMESTAMPING_US]  = "us",
+        [SOCKET_TIMESTAMPING_NS]  = "ns",
 };
 
 DEFINE_STRING_TABLE_LOOKUP(socket_timestamping, SocketTimestamping);
index 3843b1950004ed630644cb634c49a2aac3daf0db..42d2e0242ecd39c297987e03e80d14ece874db8e 100644 (file)
@@ -609,7 +609,6 @@ static int swap_coldplug(Unit *u) {
 }
 
 static void swap_dump(Unit *u, FILE *f, const char *prefix) {
-        char buf[FORMAT_TIMESPAN_MAX];
         Swap *s = SWAP(u);
         SwapParameters *p;
 
@@ -651,7 +650,7 @@ static void swap_dump(Unit *u, FILE *f, const char *prefix) {
 
         fprintf(f,
                 "%sTimeoutSec: %s\n",
-                prefix, format_timespan(buf, sizeof(buf), s->timeout_usec, USEC_PER_SEC));
+                prefix, FORMAT_TIMESPAN(s->timeout_usec, USEC_PER_SEC));
 
         if (s->control_pid > 0)
                 fprintf(f,
@@ -980,7 +979,7 @@ static int swap_stop(Unit *u) {
                 return 0;
 
         default:
-                assert_not_reached("Unexpected state.");
+                assert_not_reached();
         }
 }
 
@@ -1074,7 +1073,7 @@ static void swap_sigchld_event(Unit *u, pid_t pid, int code, int status) {
         else if (code == CLD_DUMPED)
                 f = SWAP_FAILURE_CORE_DUMP;
         else
-                assert_not_reached("Unknown code");
+                assert_not_reached();
 
         if (s->result == SWAP_SUCCESS)
                 s->result = f;
@@ -1119,7 +1118,7 @@ static void swap_sigchld_event(Unit *u, pid_t pid, int code, int status) {
                 break;
 
         default:
-                assert_not_reached("Uh, control process died at wrong time.");
+                assert_not_reached();
         }
 
         /* Notify clients about changed exit status */
@@ -1170,7 +1169,7 @@ static int swap_dispatch_timer(sd_event_source *source, usec_t usec, void *userd
                 break;
 
         default:
-                assert_not_reached("Timeout at wrong time.");
+                assert_not_reached();
         }
 
         return 0;
@@ -1202,8 +1201,9 @@ static int swap_load_proc_swaps(Manager *m, bool set_flags) {
                         continue;
                 }
 
-                if (cunescape(dev, UNESCAPE_RELAX, &d) < 0)
-                        return log_oom();
+                ssize_t l = cunescape(dev, UNESCAPE_RELAX, &d);
+                if (l < 0)
+                        return log_error_errno(l, "Failed to unescape device path: %m");
 
                 device_found_node(m, d, DEVICE_FOUND_SWAP, DEVICE_FOUND_SWAP);
 
@@ -1589,19 +1589,19 @@ static int swap_can_clean(Unit *u, ExecCleanMask *ret) {
 }
 
 static const char* const swap_exec_command_table[_SWAP_EXEC_COMMAND_MAX] = {
-        [SWAP_EXEC_ACTIVATE] = "ExecActivate",
+        [SWAP_EXEC_ACTIVATE]   = "ExecActivate",
         [SWAP_EXEC_DEACTIVATE] = "ExecDeactivate",
 };
 
 DEFINE_STRING_TABLE_LOOKUP(swap_exec_command, SwapExecCommand);
 
 static const char* const swap_result_table[_SWAP_RESULT_MAX] = {
-        [SWAP_SUCCESS] = "success",
-        [SWAP_FAILURE_RESOURCES] = "resources",
-        [SWAP_FAILURE_TIMEOUT] = "timeout",
-        [SWAP_FAILURE_EXIT_CODE] = "exit-code",
-        [SWAP_FAILURE_SIGNAL] = "signal",
-        [SWAP_FAILURE_CORE_DUMP] = "core-dump",
+        [SWAP_SUCCESS]                 = "success",
+        [SWAP_FAILURE_RESOURCES]       = "resources",
+        [SWAP_FAILURE_TIMEOUT]         = "timeout",
+        [SWAP_FAILURE_EXIT_CODE]       = "exit-code",
+        [SWAP_FAILURE_SIGNAL]          = "signal",
+        [SWAP_FAILURE_CORE_DUMP]       = "core-dump",
         [SWAP_FAILURE_START_LIMIT_HIT] = "start-limit-hit",
 };
 
index e064ad9a2dc9876ff8a4175feb8766a663cee715..12515a6a75692a859d265c59214c7bea952aff78 100644 (file)
@@ -234,7 +234,6 @@ static int timer_load(Unit *u) {
 }
 
 static void timer_dump(Unit *u, FILE *f, const char *prefix) {
-        char buf[FORMAT_TIMESPAN_MAX];
         Timer *t = TIMER(u);
         Unit *trigger;
         TimerValue *v;
@@ -257,7 +256,7 @@ static void timer_dump(Unit *u, FILE *f, const char *prefix) {
                 prefix, trigger ? trigger->id : "n/a",
                 prefix, yes_no(t->persistent),
                 prefix, yes_no(t->wake_system),
-                prefix, format_timespan(buf, sizeof(buf), t->accuracy_usec, 1),
+                prefix, FORMAT_TIMESPAN(t->accuracy_usec, 1),
                 prefix, yes_no(t->remain_after_elapse),
                 prefix, yes_no(t->fixed_random_delay),
                 prefix, yes_no(t->on_clock_change),
@@ -274,15 +273,12 @@ static void timer_dump(Unit *u, FILE *f, const char *prefix) {
                                 prefix,
                                 timer_base_to_string(v->base),
                                 strna(p));
-                } else  {
-                        char timespan1[FORMAT_TIMESPAN_MAX];
-
+                } else
                         fprintf(f,
                                 "%s%s: %s\n",
                                 prefix,
                                 timer_base_to_string(v->base),
-                                format_timespan(timespan1, sizeof(timespan1), v->value, 0));
-                }
+                                FORMAT_TIMESPAN(v->value, 0));
 }
 
 static void timer_set_state(Timer *t, TimerState state) {
@@ -355,7 +351,6 @@ static void timer_enter_elapsed(Timer *t, bool leave_around) {
 }
 
 static void add_random(Timer *t, usec_t *v) {
-        char s[FORMAT_TIMESPAN_MAX];
         usec_t add;
 
         assert(t);
@@ -373,7 +368,7 @@ static void add_random(Timer *t, usec_t *v) {
         else
                 *v += add;
 
-        log_unit_debug(UNIT(t), "Adding %s random time.", format_timespan(s, sizeof(s), add, 0));
+        log_unit_debug(UNIT(t), "Adding %s random time.", FORMAT_TIMESPAN(add, 0));
 }
 
 static void timer_enter_waiting(Timer *t, bool time_change) {
@@ -478,7 +473,7 @@ static void timer_enter_waiting(Timer *t, bool time_change) {
                                 break;
 
                         default:
-                                assert_not_reached("Unknown timer base");
+                                assert_not_reached();
                         }
 
                         v->next_elapse = usec_add(usec_shift_clock(base, CLOCK_MONOTONIC, TIMER_MONOTONIC_CLOCK(t)), v->value);
@@ -508,13 +503,12 @@ static void timer_enter_waiting(Timer *t, bool time_change) {
         }
 
         if (found_monotonic) {
-                char buf[FORMAT_TIMESPAN_MAX];
                 usec_t left;
 
                 add_random(t, &t->next_elapse_monotonic_or_boottime);
 
                 left = usec_sub_unsigned(t->next_elapse_monotonic_or_boottime, triple_timestamp_by_clock(&ts, TIMER_MONOTONIC_CLOCK(t)));
-                log_unit_debug(UNIT(t), "Monotonic timer elapses in %s.", format_timespan(buf, sizeof(buf), left, 0));
+                log_unit_debug(UNIT(t), "Monotonic timer elapses in %s.", FORMAT_TIMESPAN(left, 0));
 
                 if (t->monotonic_event_source) {
                         r = sd_event_source_set_time(t->monotonic_event_source, t->next_elapse_monotonic_or_boottime);
@@ -546,11 +540,9 @@ static void timer_enter_waiting(Timer *t, bool time_change) {
         }
 
         if (found_realtime) {
-                char buf[FORMAT_TIMESTAMP_MAX];
-
                 add_random(t, &t->next_elapse_realtime);
 
-                log_unit_debug(UNIT(t), "Realtime timer elapses at %s.", format_timestamp(buf, sizeof(buf), t->next_elapse_realtime));
+                log_unit_debug(UNIT(t), "Realtime timer elapses at %s.", FORMAT_TIMESTAMP(t->next_elapse_realtime));
 
                 if (t->realtime_event_source) {
                         r = sd_event_source_set_time(t->realtime_event_source, t->next_elapse_realtime);
@@ -664,12 +656,9 @@ static int timer_start(Unit *u) {
                         ft = timespec_load(&st.st_mtim);
                         if (ft < now(CLOCK_REALTIME))
                                 t->last_trigger.realtime = ft;
-                        else {
-                                char z[FORMAT_TIMESTAMP_MAX];
-
+                        else
                                 log_unit_warning(u, "Not using persistent file timestamp %s as it is in the future.",
-                                                 format_timestamp(z, sizeof(z), ft));
-                        }
+                                                 FORMAT_TIMESTAMP(ft));
 
                 } else if (errno == ENOENT)
                         /* The timer has never run before, make sure a stamp file exists. */
@@ -808,7 +797,7 @@ static void timer_trigger_notify(Unit *u, Unit *other) {
                 break;
 
         default:
-                assert_not_reached("Unknown timer state");
+                assert_not_reached();
         }
 }
 
@@ -902,19 +891,19 @@ static int timer_can_clean(Unit *u, ExecCleanMask *ret) {
 }
 
 static const char* const timer_base_table[_TIMER_BASE_MAX] = {
-        [TIMER_ACTIVE] = "OnActiveSec",
-        [TIMER_BOOT] = "OnBootSec",
-        [TIMER_STARTUP] = "OnStartupSec",
-        [TIMER_UNIT_ACTIVE] = "OnUnitActiveSec",
+        [TIMER_ACTIVE]        = "OnActiveSec",
+        [TIMER_BOOT]          = "OnBootSec",
+        [TIMER_STARTUP]       = "OnStartupSec",
+        [TIMER_UNIT_ACTIVE]   = "OnUnitActiveSec",
         [TIMER_UNIT_INACTIVE] = "OnUnitInactiveSec",
-        [TIMER_CALENDAR] = "OnCalendar"
+        [TIMER_CALENDAR]      = "OnCalendar"
 };
 
 DEFINE_STRING_TABLE_LOOKUP(timer_base, TimerBase);
 
 static const char* const timer_result_table[_TIMER_RESULT_MAX] = {
-        [TIMER_SUCCESS] = "success",
-        [TIMER_FAILURE_RESOURCES] = "resources",
+        [TIMER_SUCCESS]                 = "success",
+        [TIMER_FAILURE_RESOURCES]       = "resources",
         [TIMER_FAILURE_START_LIMIT_HIT] = "start-limit-hit",
 };
 
index 689a536549df5e2ab216813fbb52baf449a8b895..ab0f03a0ca5309ba7865cc2e808966b71110fe3a 100644 (file)
@@ -602,7 +602,6 @@ static void print_unit_dependency_mask(FILE *f, const char *kind, UnitDependency
 void unit_dump(Unit *u, FILE *f, const char *prefix) {
         char *t, **j;
         const char *prefix2;
-        char timestamp[5][FORMAT_TIMESTAMP_MAX], timespan[FORMAT_TIMESPAN_MAX];
         Unit *following;
         _cleanup_set_free_ Set *following_set = NULL;
         CGroupMask m;
@@ -640,11 +639,11 @@ void unit_dump(Unit *u, FILE *f, const char *prefix) {
                 prefix, strna(u->instance),
                 prefix, unit_load_state_to_string(u->load_state),
                 prefix, unit_active_state_to_string(unit_active_state(u)),
-                prefix, strna(format_timestamp(timestamp[0], sizeof(timestamp[0]), u->state_change_timestamp.realtime)),
-                prefix, strna(format_timestamp(timestamp[1], sizeof(timestamp[1]), u->inactive_exit_timestamp.realtime)),
-                prefix, strna(format_timestamp(timestamp[2], sizeof(timestamp[2]), u->active_enter_timestamp.realtime)),
-                prefix, strna(format_timestamp(timestamp[3], sizeof(timestamp[3]), u->active_exit_timestamp.realtime)),
-                prefix, strna(format_timestamp(timestamp[4], sizeof(timestamp[4]), u->inactive_enter_timestamp.realtime)),
+                prefix, strna(FORMAT_TIMESTAMP(u->state_change_timestamp.realtime)),
+                prefix, strna(FORMAT_TIMESTAMP(u->inactive_exit_timestamp.realtime)),
+                prefix, strna(FORMAT_TIMESTAMP(u->active_enter_timestamp.realtime)),
+                prefix, strna(FORMAT_TIMESTAMP(u->active_exit_timestamp.realtime)),
+                prefix, strna(FORMAT_TIMESTAMP(u->inactive_enter_timestamp.realtime)),
                 prefix, yes_no(unit_may_gc(u)),
                 prefix, yes_no(unit_need_daemon_reload(u)),
                 prefix, yes_no(u->transient),
@@ -741,7 +740,7 @@ void unit_dump(Unit *u, FILE *f, const char *prefix) {
                 fprintf(f, "%s\tSuccess Action Exit Status: %i\n", prefix, u->success_action_exit_status);
 
         if (u->job_timeout != USEC_INFINITY)
-                fprintf(f, "%s\tJob Timeout: %s\n", prefix, format_timespan(timespan, sizeof(timespan), u->job_timeout, 0));
+                fprintf(f, "%s\tJob Timeout: %s\n", prefix, FORMAT_TIMESPAN(u->job_timeout, 0));
 
         if (u->job_timeout_action != EMERGENCY_ACTION_NONE)
                 fprintf(f, "%s\tJob Timeout Action: %s\n", prefix, emergency_action_to_string(u->job_timeout_action));
@@ -756,14 +755,14 @@ void unit_dump(Unit *u, FILE *f, const char *prefix) {
                 fprintf(f,
                         "%s\tCondition Timestamp: %s\n"
                         "%s\tCondition Result: %s\n",
-                        prefix, strna(format_timestamp(timestamp[0], sizeof(timestamp[0]), u->condition_timestamp.realtime)),
+                        prefix, strna(FORMAT_TIMESTAMP(u->condition_timestamp.realtime)),
                         prefix, yes_no(u->condition_result));
 
         if (dual_timestamp_is_set(&u->assert_timestamp))
                 fprintf(f,
                         "%s\tAssert Timestamp: %s\n"
                         "%s\tAssert Result: %s\n",
-                        prefix, strna(format_timestamp(timestamp[0], sizeof(timestamp[0]), u->assert_timestamp.realtime)),
+                        prefix, strna(FORMAT_TIMESTAMP(u->assert_timestamp.realtime)),
                         prefix, yes_no(u->assert_result));
 
         for (UnitDependency d = 0; d < _UNIT_DEPENDENCY_MAX; d++) {
index 30afd5a7767a80e20c907486a7f5fa0686999a64..62739260137005e3c961ee6e9981bcdadb6f1d43 100644 (file)
@@ -418,7 +418,7 @@ bool unit_may_gc(Unit *u) {
                 break;
 
         default:
-                assert_not_reached("Unknown garbage collection mode");
+                assert_not_reached();
         }
 
         if (u->cgroup_path) {
@@ -2273,8 +2273,6 @@ static int unit_log_resources(Unit *u) {
 
         (void) unit_get_cpu_usage(u, &nsec);
         if (nsec != NSEC_INFINITY) {
-                char buf[FORMAT_TIMESPAN_MAX] = "";
-
                 /* Format the CPU time for inclusion in the structured log message */
                 if (asprintf(&t, "CPU_USAGE_NSEC=%" PRIu64, nsec) < 0) {
                         r = log_oom();
@@ -2283,8 +2281,7 @@ static int unit_log_resources(Unit *u) {
                 iovec[n_iovec++] = IOVEC_MAKE_STRING(t);
 
                 /* Format the CPU time for inclusion in the human language message string */
-                format_timespan(buf, sizeof(buf), nsec / NSEC_PER_USEC, USEC_PER_MSEC);
-                t = strjoin("consumed ", buf, " CPU time");
+                t = strjoin("consumed ", FORMAT_TIMESPAN(nsec / NSEC_PER_USEC, USEC_PER_MSEC), " CPU time");
                 if (!t) {
                         r = log_oom();
                         goto finish;
@@ -2298,7 +2295,6 @@ static int unit_log_resources(Unit *u) {
         }
 
         for (CGroupIOAccountingMetric k = 0; k < _CGROUP_IO_ACCOUNTING_METRIC_MAX; k++) {
-                char buf[FORMAT_BYTES_MAX] = "";
                 uint64_t value = UINT64_MAX;
 
                 assert(io_fields[k]);
@@ -2322,14 +2318,14 @@ static int unit_log_resources(Unit *u) {
                  * for the bytes counters (and not for the operations counters) */
                 if (k == CGROUP_IO_READ_BYTES) {
                         assert(!rr);
-                        rr = strjoin("read ", format_bytes(buf, sizeof(buf), value), " from disk");
+                        rr = strjoin("read ", strna(FORMAT_BYTES(value)), " from disk");
                         if (!rr) {
                                 r = log_oom();
                                 goto finish;
                         }
                 } else if (k == CGROUP_IO_WRITE_BYTES) {
                         assert(!wr);
-                        wr = strjoin("written ", format_bytes(buf, sizeof(buf), value), " to disk");
+                        wr = strjoin("written ", strna(FORMAT_BYTES(value)), " to disk");
                         if (!wr) {
                                 r = log_oom();
                                 goto finish;
@@ -2363,7 +2359,6 @@ static int unit_log_resources(Unit *u) {
         }
 
         for (CGroupIPAccountingMetric m = 0; m < _CGROUP_IP_ACCOUNTING_METRIC_MAX; m++) {
-                char buf[FORMAT_BYTES_MAX] = "";
                 uint64_t value = UINT64_MAX;
 
                 assert(ip_fields[m]);
@@ -2387,14 +2382,14 @@ static int unit_log_resources(Unit *u) {
                  * bytes counters (and not for the packets counters) */
                 if (m == CGROUP_IP_INGRESS_BYTES) {
                         assert(!igress);
-                        igress = strjoin("received ", format_bytes(buf, sizeof(buf), value), " IP traffic");
+                        igress = strjoin("received ", strna(FORMAT_BYTES(value)), " IP traffic");
                         if (!igress) {
                                 r = log_oom();
                                 goto finish;
                         }
                 } else if (m == CGROUP_IP_EGRESS_BYTES) {
                         assert(!egress);
-                        egress = strjoin("sent ", format_bytes(buf, sizeof(buf), value), " IP traffic");
+                        egress = strjoin("sent ", strna(FORMAT_BYTES(value)), " IP traffic");
                         if (!egress) {
                                 r = log_oom();
                                 goto finish;
@@ -2596,7 +2591,7 @@ static bool unit_process_job(Job *j, UnitActiveState ns, UnitNotifyFlags flags)
                 break;
 
         default:
-                assert_not_reached("Job type unknown");
+                assert_not_reached();
         }
 
         return unexpected;
@@ -2988,7 +2983,7 @@ bool unit_job_is_applicable(Unit *u, JobType j) {
                 return unit_can_reload(u) && unit_can_start(u);
 
         default:
-                assert_not_reached("Invalid job type");
+                assert_not_reached();
         }
 }
 
@@ -4464,7 +4459,7 @@ static int operation_to_signal(const KillContext *c, KillOperation k, bool *note
                 return c->watchdog_signal;
 
         default:
-                assert_not_reached("KillOperation unknown");
+                assert_not_reached();
         }
 }
 
index 759104ffa796979ffc5d523f81748a13fdbbf514..48074d8ca5b680b6723d79c043a4c97bc068b459 100644 (file)
@@ -631,6 +631,9 @@ typedef struct UnitVTable {
          * exit code of the "main" process of the service or similar. */
         int (*exit_status)(Unit *u);
 
+        /* Return a copy of the status string pointer. */
+        const char* (*status_text)(Unit *u);
+
         /* Like the enumerate() callback further down, but only enumerates the perpetual units, i.e. all units that
          * unconditionally exist and are always active. The main reason to keep both enumeration functions separate is
          * philosophical: the state of perpetual units should be put in place by coldplug(), while the state of those
@@ -744,6 +747,12 @@ static inline bool unit_is_extrinsic(Unit *u) {
                 (UNIT_VTABLE(u)->is_extrinsic && UNIT_VTABLE(u)->is_extrinsic(u));
 }
 
+static inline const char* unit_status_text(Unit *u) {
+        if (u && UNIT_VTABLE(u)->status_text)
+                return UNIT_VTABLE(u)->status_text(u);
+        return NULL;
+}
+
 void unit_add_to_load_queue(Unit *u);
 void unit_add_to_dbus_queue(Unit *u);
 void unit_add_to_cleanup_queue(Unit *u);
index def3650bb4588107bba8aea3912660f473dac955..d370de290af5a2b68b5dccc0cf9a9ff893439a7a 100644 (file)
@@ -331,7 +331,7 @@ static int parse_argv(int argc, char *argv[]) {
                         return -EINVAL;
 
                 default:
-                        assert_not_reached("Unhandled option");
+                        assert_not_reached();
                 }
 
         if (arg_since != USEC_INFINITY && arg_until != USEC_INFINITY &&
@@ -645,15 +645,11 @@ static int print_info(FILE *file, sd_journal *j, bool need_space) {
                 usec_t u;
 
                 r = safe_atou64(timestamp, &u);
-                if (r >= 0) {
-                        char absolute[FORMAT_TIMESTAMP_MAX], relative[FORMAT_TIMESPAN_MAX];
+                if (r >= 0)
+                        fprintf(file, "     Timestamp: %s (%s)\n",
+                                FORMAT_TIMESTAMP(u), FORMAT_TIMESTAMP_RELATIVE(u));
 
-                        fprintf(file,
-                                "     Timestamp: %s (%s)\n",
-                                format_timestamp(absolute, sizeof(absolute), u),
-                                format_timestamp_relative(relative, sizeof(relative), u));
-
-                } else
+                else
                         fprintf(file, "     Timestamp: %s\n", timestamp);
         }
 
@@ -697,7 +693,6 @@ static int print_info(FILE *file, sd_journal *j, bool need_space) {
         if (filename) {
                 const char *state = NULL, *color = NULL;
                 uint64_t size = UINT64_MAX;
-                char buf[FORMAT_BYTES_MAX];
 
                 analyze_coredump_file(filename, &state, &color, &size);
 
@@ -712,9 +707,8 @@ static int print_info(FILE *file, sd_journal *j, bool need_space) {
                         ansi_normal());
 
                 if (size != UINT64_MAX)
-                        fprintf(file,
-                                "     Disk Size: %s\n",
-                                format_bytes(buf, sizeof(buf), size));
+                        fprintf(file, "     Disk Size: %s\n", FORMAT_BYTES(size));
+
         } else if (coredump)
                 fprintf(file, "       Storage: journal\n");
         else
index 0edb1b40a72286800c79f69ca0735f57ada3b0c3..e46b324cdf77fb003f4f290a1978a2776ecb65c5 100644 (file)
@@ -153,6 +153,8 @@ static int parse_package_metadata(const char *name, JsonVariant *id_json, Elf *e
                                             program_header->p_offset,
                                             program_header->p_filesz,
                                             ELF_T_NHDR);
+                if (!data)
+                        continue;
 
                 while (note_offset < data->d_size &&
                        (note_offset = gelf_getnote(data, note_offset, &note_header, &name_offset, &desc_offset)) > 0) {
index 50de685cd4a43fd8dd7a8e295ab1e65032c573dd..f880a79a822fe73577dfc7d008c644a4549c2d15 100644 (file)
@@ -193,7 +193,7 @@ static int transcode(
         switch (arg_transcode) {
 
         case TRANSCODE_BASE64: {
-                char *buf = NULL;
+                char *buf;
                 ssize_t l;
 
                 l = base64mem_full(input, input_size, 79, &buf);
@@ -232,7 +232,7 @@ static int transcode(
                 return r;
 
         default:
-                assert_not_reached("Unexpected transcoding mode");
+                assert_not_reached();
         }
 }
 
@@ -362,7 +362,7 @@ static int verb_encrypt(int argc, char **argv, void *userdata) {
 
         assert(argc == 3);
 
-        input_path = (isempty(argv[1]) || streq(argv[1], "-")) ? NULL : argv[1];
+        input_path = empty_or_dash(argv[1]) ? NULL : argv[1];
 
         if (input_path)
                 r = read_full_file_full(AT_FDCWD, input_path, UINT64_MAX, CREDENTIAL_SIZE_MAX, READ_FULL_FILE_SECURE|READ_FULL_FILE_FAIL_WHEN_LARGER, NULL, &plaintext, &plaintext_size);
@@ -373,7 +373,7 @@ static int verb_encrypt(int argc, char **argv, void *userdata) {
         if (r < 0)
                 return log_error_errno(r, "Failed to read plaintext: %m");
 
-        output_path = (isempty(argv[2]) || streq(argv[2], "-")) ? NULL : argv[2];
+        output_path = empty_or_dash(argv[2]) ? NULL : argv[2];
 
         if (arg_name_any)
                 name = NULL;
@@ -455,7 +455,7 @@ static int verb_decrypt(int argc, char **argv, void *userdata) {
 
         assert(IN_SET(argc, 2, 3));
 
-        input_path = (isempty(argv[1]) || streq(argv[1], "-")) ? NULL : argv[1];
+        input_path = empty_or_dash(argv[1]) ? NULL : argv[1];
 
         if (input_path)
                 r = read_full_file_full(AT_FDCWD, argv[1], UINT64_MAX, CREDENTIAL_ENCRYPTED_SIZE_MAX, READ_FULL_FILE_UNBASE64|READ_FULL_FILE_FAIL_WHEN_LARGER, NULL, &input, &input_size);
@@ -704,30 +704,20 @@ static int parse_argv(int argc, char *argv[]) {
                         arg_with_key = CRED_AES256_GCM_BY_TPM2_HMAC;
                         break;
 
-                case ARG_TPM2_DEVICE: {
-                        _cleanup_free_ char *device = NULL;
-
+                case ARG_TPM2_DEVICE:
                         if (streq(optarg, "list"))
                                 return tpm2_list_devices();
 
-                        if (!streq(optarg, "auto")) {
-                                device = strdup(optarg);
-                                if (!device)
-                                        return log_oom();
-                        }
-
-                        arg_tpm2_device = TAKE_PTR(device);
+                        arg_tpm2_device = streq(optarg, "auto") ? NULL : optarg;
                         break;
-                }
-
-                case ARG_TPM2_PCRS: {
-                        uint32_t mask;
 
+                case ARG_TPM2_PCRS:
                         if (isempty(optarg)) {
                                 arg_tpm2_pcr_mask = 0;
                                 break;
                         }
 
+                        uint32_t mask;
                         r = tpm2_parse_pcrs(optarg, &mask);
                         if (r < 0)
                                 return r;
@@ -738,7 +728,6 @@ static int parse_argv(int argc, char *argv[]) {
                                 arg_tpm2_pcr_mask |= mask;
 
                         break;
-                }
 
                 case ARG_NAME:
                         if (isempty(optarg)) {
@@ -772,7 +761,7 @@ static int parse_argv(int argc, char *argv[]) {
                         return -EINVAL;
 
                 default:
-                        assert_not_reached("Unhandled option");
+                        assert_not_reached();
                 }
         }
 
index 9c1478c474e34a1476c1112277a5caf0d89b27f0..697b4c2335b36d1b12deb6482bed21bfcec50d97 100644 (file)
@@ -65,6 +65,7 @@ int enroll_tpm2(struct crypt_device *cd,
         _cleanup_(erase_and_freep) char *base64_encoded = NULL;
         size_t secret_size, secret2_size, blob_size, hash_size;
         _cleanup_free_ void *blob = NULL, *hash = NULL;
+        uint16_t pcr_bank;
         const char *node;
         int r, keyslot;
 
@@ -75,7 +76,7 @@ int enroll_tpm2(struct crypt_device *cd,
 
         assert_se(node = crypt_get_device_name(cd));
 
-        r = tpm2_seal(device, pcr_mask, &secret, &secret_size, &blob, &blob_size, &hash, &hash_size);
+        r = tpm2_seal(device, pcr_mask, &secret, &secret_size, &blob, &blob_size, &hash, &hash_size, &pcr_bank);
         if (r < 0)
                 return r;
 
@@ -92,7 +93,7 @@ int enroll_tpm2(struct crypt_device *cd,
 
         /* Quick verification that everything is in order, we are not in a hurry after all. */
         log_debug("Unsealing for verification...");
-        r = tpm2_unseal(device, pcr_mask, blob, blob_size, hash, hash_size, &secret2, &secret2_size);
+        r = tpm2_unseal(device, pcr_mask, pcr_bank, blob, blob_size, hash, hash_size, &secret2, &secret2_size);
         if (r < 0)
                 return r;
 
@@ -118,7 +119,7 @@ int enroll_tpm2(struct crypt_device *cd,
         if (keyslot < 0)
                 return log_error_errno(keyslot, "Failed to add new TPM2 key to %s: %m", node);
 
-        r = tpm2_make_luks2_json(keyslot, pcr_mask, blob, blob_size, hash, hash_size, &v);
+        r = tpm2_make_luks2_json(keyslot, pcr_mask, pcr_bank, blob, blob_size, hash, hash_size, &v);
         if (r < 0)
                 return log_error_errno(r, "Failed to prepare TPM2 JSON token object: %m");
 
index 2255946643b3a9b842895eb79156b303a2ee9529..8042a0fe835883808368d9ab4e42562b11b55337 100644 (file)
@@ -367,7 +367,7 @@ int wipe_slots(struct crypt_device *cd,
 
                 break;
         default:
-                assert_not_reached("Unexpected wipe scope");
+                assert_not_reached();
         }
 
         /* Then add all slots that match a token type */
index d253b2bc0da7b463c3079325fafec048556f1550..f2e194e88c5e4479c85781972f4610a47ac81cbb 100644 (file)
@@ -358,7 +358,7 @@ static int parse_argv(int argc, char *argv[]) {
                         return -EINVAL;
 
                 default:
-                        assert_not_reached("Unhandled option");
+                        assert_not_reached();
                 }
         }
 
diff --git a/src/cryptsetup/cryptsetup-tokens/cryptsetup-token-systemd-tpm2.c b/src/cryptsetup/cryptsetup-tokens/cryptsetup-token-systemd-tpm2.c
new file mode 100644 (file)
index 0000000..d3aa092
--- /dev/null
@@ -0,0 +1,236 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+
+#include <errno.h>
+#include <libcryptsetup.h>
+
+#include "cryptsetup-token.h"
+#include "cryptsetup-token-util.h"
+#include "hexdecoct.h"
+#include "luks2-tpm2.h"
+#include "memory-util.h"
+#include "tpm2-util.h"
+#include "version.h"
+
+#define TOKEN_NAME "systemd-tpm2"
+#define TOKEN_VERSION_MAJOR "1"
+#define TOKEN_VERSION_MINOR "0"
+
+/* for libcryptsetup debug purpose */
+_public_ const char *cryptsetup_token_version(void) {
+
+        return TOKEN_VERSION_MAJOR "." TOKEN_VERSION_MINOR " systemd-v" STRINGIFY(PROJECT_VERSION) " (" GIT_VERSION ")";
+}
+
+static int log_debug_open_error(struct crypt_device *cd, int r) {
+        if (r == -EAGAIN) {
+                crypt_log_debug(cd, "TPM2 device not found.");
+                return r;
+        } else if (r == -ENXIO) {
+                crypt_log_debug(cd, "No matching TPM2 token data found.");
+                return r;
+        }
+
+        return crypt_log_debug_errno(cd, r, TOKEN_NAME " open failed: %m.");
+}
+
+/*
+ * This function is called from within following libcryptsetup calls
+ * provided conditions further below are met:
+ *
+ * crypt_activate_by_token(), crypt_activate_by_token_type(type == 'systemd-tpm2'):
+ *
+ * - token is assigned to at least one luks2 keyslot eligible to activate LUKS2 device
+ *   (alternatively: name is set to null, flags contains CRYPT_ACTIVATE_ALLOW_UNBOUND_KEY
+ *    and token is assigned to at least single keyslot).
+ *
+ * - if plugin defines validate funtion (see cryptsetup_token_validate below) it must have
+ *   passed the check (aka return 0)
+ */
+_public_ int cryptsetup_token_open(
+                struct crypt_device *cd, /* is always LUKS2 context */
+                int token /* is always >= 0 */,
+                char **password, /* freed by cryptsetup_token_buffer_free */
+                size_t *password_len,
+                void *usrptr /* plugin defined parameter passed to crypt_activate_by_token*() API */) {
+
+        int r;
+        const char *json;
+        size_t blob_size, policy_hash_size, decrypted_key_size;
+        uint32_t pcr_mask;
+        uint16_t pcr_bank;
+        systemd_tpm2_plugin_params params = {
+                .search_pcr_mask = UINT32_MAX
+        };
+        _cleanup_free_ void *blob = NULL, *policy_hash = NULL;
+        _cleanup_free_ char *base64_blob = NULL, *hex_policy_hash = NULL;
+        _cleanup_(erase_and_freep) void *decrypted_key = NULL;
+        _cleanup_(erase_and_freep) char *base64_encoded = NULL;
+
+        assert(password);
+        assert(password_len);
+        assert(token >= 0);
+
+        /* This must not fail at this moment (internal error) */
+        r = crypt_token_json_get(cd, token, &json);
+        assert(token == r);
+        assert(json);
+
+        if (usrptr)
+                params = *(systemd_tpm2_plugin_params *)usrptr;
+
+        r = parse_luks2_tpm2_data(json, params.search_pcr_mask, &pcr_mask, &pcr_bank, &base64_blob, &hex_policy_hash);
+        if (r < 0)
+                return log_debug_open_error(cd, r);
+
+        /* should not happen since cryptsetup_token_validate have passed */
+        r = unbase64mem(base64_blob, SIZE_MAX, &blob, &blob_size);
+        if (r < 0)
+                return log_debug_open_error(cd, r);
+
+        /* should not happen since cryptsetup_token_validate have passed */
+        r = unhexmem(hex_policy_hash, SIZE_MAX, &policy_hash, &policy_hash_size);
+        if (r < 0)
+                return log_debug_open_error(cd, r);
+
+        r = acquire_luks2_key(
+                        pcr_mask,
+                        pcr_bank,
+                        params.device,
+                        blob,
+                        blob_size,
+                        policy_hash,
+                        policy_hash_size,
+                        &decrypted_key,
+                        &decrypted_key_size);
+        if (r < 0)
+                return log_debug_open_error(cd, r);
+
+        /* Before using this key as passphrase we base64 encode it, for compat with homed */
+        r = base64mem(decrypted_key, decrypted_key_size, &base64_encoded);
+        if (r < 0)
+                return log_debug_open_error(cd, r);
+
+        /* free'd automaticaly by libcryptsetup */
+        *password_len = strlen(base64_encoded);
+        *password = TAKE_PTR(base64_encoded);
+
+        return 0;
+}
+
+/*
+ * libcryptsetup callback for memory deallocation of 'password' parameter passed in
+ * any crypt_token_open_* plugin function
+ */
+_public_ void cryptsetup_token_buffer_free(void *buffer, size_t buffer_len) {
+        erase_and_free(buffer);
+}
+
+/*
+ * prints systemd-tpm2 token content in crypt_dump().
+ * 'type' and 'keyslots' fields are printed by libcryptsetup
+ */
+_public_ void cryptsetup_token_dump(
+                struct crypt_device *cd /* is always LUKS2 context */,
+                const char *json /* validated 'systemd-tpm2' token if cryptsetup_token_validate is defined */) {
+
+        int r;
+        uint32_t i, pcr_mask;
+        uint16_t pcr_bank;
+        size_t decoded_blob_size;
+        _cleanup_free_ char *base64_blob = NULL, *hex_policy_hash = NULL,
+                            *pcrs_str = NULL, *blob_str = NULL, *policy_hash_str = NULL;
+        _cleanup_free_ void *decoded_blob = NULL;
+
+        assert(json);
+
+        r = parse_luks2_tpm2_data(json, UINT32_MAX, &pcr_mask, &pcr_bank, &base64_blob, &hex_policy_hash);
+        if (r < 0)
+                return (void) crypt_log_debug_errno(cd, r, "Failed to parse " TOKEN_NAME " metadata: %m.");
+
+        for (i = 0; i < TPM2_PCRS_MAX; i++) {
+                if ((pcr_mask & (UINT32_C(1) << i)) &&
+                    ((r = strextendf_with_separator(&pcrs_str, ", ", "%" PRIu32, i)) < 0))
+                        return (void) crypt_log_debug_errno(cd, r, "Can not dump " TOKEN_NAME " content: %m");
+        }
+
+        r = unbase64mem(base64_blob, SIZE_MAX, &decoded_blob, &decoded_blob_size);
+        if (r < 0)
+                return (void) crypt_log_debug_errno(cd, r, "Can not dump " TOKEN_NAME " content: %m");
+
+        r = crypt_dump_buffer_to_hex_string(decoded_blob, decoded_blob_size, &blob_str);
+        if (r < 0)
+                return (void) crypt_log_debug_errno(cd, r, "Can not dump " TOKEN_NAME " content: %m");
+
+        r = crypt_dump_hex_string(hex_policy_hash, &policy_hash_str);
+        if (r < 0)
+                return (void) crypt_log_debug_errno(cd, r, "Can not dump " TOKEN_NAME " content: %m");
+
+        crypt_log(cd, "\ttpm2-pcrs:  %s\n", strna(pcrs_str));
+        crypt_log(cd, "\ttpm2-bank:  %s\n", strna(tpm2_pcr_bank_to_string(pcr_bank)));
+        crypt_log(cd, "\ttmp2-blob:  %s\n", blob_str);
+        crypt_log(cd, "\ttmp2-policy-hash:" CRYPT_DUMP_LINE_SEP "%s\n", policy_hash_str);
+}
+
+/*
+ * Note:
+ *   If plugin is available in library path, it's called in before following libcryptsetup calls:
+ *
+ *   crypt_token_json_set, crypt_dump, any crypt_activate_by_token_* flavour
+ */
+_public_ int cryptsetup_token_validate(
+                struct crypt_device *cd, /* is always LUKS2 context */
+                const char *json /* contains valid 'type' and 'keyslots' fields. 'type' is 'systemd-tpm2' */) {
+
+        int r;
+        JsonVariant *w, *e;
+        _cleanup_(json_variant_unrefp) JsonVariant *v = NULL;
+
+        assert(json);
+
+        r = json_parse(json, 0, &v, NULL, NULL);
+        if (r < 0)
+                return crypt_log_debug_errno(cd, r, "Could not parse " TOKEN_NAME " json object: %m");
+
+        w = json_variant_by_key(v, "tpm2-pcrs");
+        if (!w || !json_variant_is_array(w)) {
+                crypt_log_debug(cd, "TPM2 token data lacks 'tpm2-pcrs' field.");
+                return 1;
+        }
+
+        JSON_VARIANT_ARRAY_FOREACH(e, w) {
+                uintmax_t u;
+
+                if (!json_variant_is_number(e)) {
+                        crypt_log_debug(cd, "TPM2 PCR is not a number.");
+                        return 1;
+                }
+
+                u = json_variant_unsigned(e);
+                if (u >= TPM2_PCRS_MAX) {
+                        crypt_log_debug(cd, "TPM2 PCR number out of range.");
+                        return 1;
+                }
+        }
+
+        w = json_variant_by_key(v, "tpm2-blob");
+        if (!w || !json_variant_is_string(w)) {
+                crypt_log_debug(cd, "TPM2 token data lacks 'tpm2-blob' field.");
+                return 1;
+        }
+
+        r = unbase64mem(json_variant_string(w), SIZE_MAX, NULL, NULL);
+        if (r < 0)
+                return crypt_log_debug_errno(cd, r, "Invalid base64 data in 'tpm2-blob' field: %m");
+
+        w = json_variant_by_key(v, "tpm2-policy-hash");
+        if (!w || !json_variant_is_string(w)) {
+                crypt_log_debug(cd, "TPM2 token data lacks 'tpm2-policy-hash' field.");
+                return 1;
+        }
+
+        r = unhexmem(json_variant_string(w), SIZE_MAX, NULL, NULL);
+        if (r < 0)
+                return crypt_log_debug_errno(cd, r, "Invalid base64 data in 'tpm2-policy-hash' field: %m");
+
+        return 0;
+}
diff --git a/src/cryptsetup/cryptsetup-tokens/cryptsetup-token-util.c b/src/cryptsetup/cryptsetup-tokens/cryptsetup-token-util.c
new file mode 100644 (file)
index 0000000..f4086ae
--- /dev/null
@@ -0,0 +1,58 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+
+#include "cryptsetup-token-util.h"
+#include "string-util.h"
+
+int crypt_dump_buffer_to_hex_string(
+                const char *buf,
+                size_t buf_size,
+                char **ret_dump_str) {
+
+        int r;
+        _cleanup_free_ char *dump_str = NULL;
+
+        assert(buf || !buf_size);
+        assert(ret_dump_str);
+
+        for (size_t i = 0; i < buf_size; i++) {
+                /* crypt_dump() breaks line after every
+                 * 16th couple of chars in dumped hexstring */
+                r = strextendf_with_separator(
+                        &dump_str,
+                        (i && !(i % 16)) ? CRYPT_DUMP_LINE_SEP : " ",
+                        "%02hhx", buf[i]);
+                if (r < 0)
+                        return r;
+        }
+
+        *ret_dump_str = TAKE_PTR(dump_str);
+
+        return 0;
+}
+
+int crypt_dump_hex_string(const char *hex_str, char **ret_dump_str) {
+
+        int r;
+        size_t len;
+        _cleanup_free_ char *dump_str = NULL;
+
+        assert(hex_str);
+        assert(ret_dump_str);
+
+        len = strlen(hex_str) >> 1;
+
+        for (size_t i = 0; i < len; i++) {
+                /* crypt_dump() breaks line after every
+                 * 16th couple of chars in dumped hexstring */
+                r = strextendf_with_separator(
+                        &dump_str,
+                        (i && !(i % 16)) ? CRYPT_DUMP_LINE_SEP : " ",
+                        "%.2s", hex_str + (i<<1));
+                if (r < 0)
+                        return r;
+        }
+
+        *ret_dump_str = TAKE_PTR(dump_str);
+
+        return 0;
+}
diff --git a/src/cryptsetup/cryptsetup-tokens/cryptsetup-token-util.h b/src/cryptsetup/cryptsetup-tokens/cryptsetup-token-util.h
new file mode 100644 (file)
index 0000000..b8ea4c2
--- /dev/null
@@ -0,0 +1,27 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+
+#pragma once
+
+#include <stddef.h>
+
+/* crypt_dump() internal indentation magic */
+#define CRYPT_DUMP_LINE_SEP "\n\t            "
+
+#define crypt_log_debug(cd, ...) crypt_logf(cd, CRYPT_LOG_DEBUG,  __VA_ARGS__)
+#define crypt_log_error(cd, ...) crypt_logf(cd, CRYPT_LOG_ERROR,  __VA_ARGS__)
+#define crypt_log(cd, ...)       crypt_logf(cd, CRYPT_LOG_NORMAL, __VA_ARGS__)
+
+#define crypt_log_debug_errno(cd, e, ...) ({ \
+        int _e = abs(e), _s = errno; \
+        errno = _e; \
+        crypt_logf(cd, CRYPT_LOG_DEBUG, __VA_ARGS__); \
+        errno = _s; \
+        -_e; \
+})
+
+int crypt_dump_buffer_to_hex_string(
+                const char *buf,
+                size_t buf_size,
+                char **ret_dump_str);
+
+int crypt_dump_hex_string(const char *hex_str, char **ret_dump_str);
diff --git a/src/cryptsetup/cryptsetup-tokens/cryptsetup-token.h b/src/cryptsetup/cryptsetup-tokens/cryptsetup-token.h
new file mode 100644 (file)
index 0000000..010e010
--- /dev/null
@@ -0,0 +1,15 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+#pragma once
+
+/* for more information see libcryptsetup.h crypt-tokens section */
+
+const char *cryptsetup_token_version(void);
+
+int cryptsetup_token_open(struct crypt_device *cd, int token,
+        char **password, size_t *password_len, void *usrptr);
+
+void cryptsetup_token_dump(struct crypt_device *cd, const char *json);
+
+int cryptsetup_token_validate(struct crypt_device *cd, const char *json);
+
+void cryptsetup_token_buffer_free(void *buffer, size_t buffer_len);
diff --git a/src/cryptsetup/cryptsetup-tokens/cryptsetup-token.sym b/src/cryptsetup/cryptsetup-tokens/cryptsetup-token.sym
new file mode 100644 (file)
index 0000000..bddf1b5
--- /dev/null
@@ -0,0 +1,18 @@
+/***
+  SPDX-License-Identifier: LGPL-2.1-or-later
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+***/
+
+CRYPTSETUP_TOKEN_1.0 {
+global:
+        cryptsetup_token_open;
+        cryptsetup_token_buffer_free;
+        cryptsetup_token_validate;
+        cryptsetup_token_dump;
+        cryptsetup_token_version;
+local: *;
+};
diff --git a/src/cryptsetup/cryptsetup-tokens/luks2-tpm2.c b/src/cryptsetup/cryptsetup-tokens/luks2-tpm2.c
new file mode 100644 (file)
index 0000000..a5571f3
--- /dev/null
@@ -0,0 +1,129 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+
+#include "alloc-util.h"
+#include "hexdecoct.h"
+#include "json.h"
+#include "luks2-tpm2.h"
+#include "parse-util.h"
+#include "random-util.h"
+#include "tpm2-util.h"
+
+int acquire_luks2_key(
+                uint32_t pcr_mask,
+                uint16_t pcr_bank,
+                const char *device,
+                const void *key_data,
+                size_t key_data_size,
+                const void *policy_hash,
+                size_t policy_hash_size,
+                void **ret_decrypted_key,
+                size_t *ret_decrypted_key_size) {
+
+        _cleanup_free_ char *auto_device = NULL;
+        int r;
+
+        assert(ret_decrypted_key);
+        assert(ret_decrypted_key_size);
+
+        if (!device) {
+                r = tpm2_find_device_auto(LOG_DEBUG, &auto_device);
+                if (r == -ENODEV)
+                        return -EAGAIN; /* Tell the caller to wait for a TPM2 device to show up */
+                if (r < 0)
+                        return r;
+
+                device = auto_device;
+        }
+
+        return tpm2_unseal(
+                        device,
+                        pcr_mask, pcr_bank,
+                        key_data, key_data_size,
+                        policy_hash, policy_hash_size,
+                        ret_decrypted_key, ret_decrypted_key_size);
+}
+
+/* this function expects valid "systemd-tpm2" in json */
+int parse_luks2_tpm2_data(
+                const char *json,
+                uint32_t search_pcr_mask,
+                uint32_t *ret_pcr_mask,
+                uint16_t *ret_pcr_bank,
+                char **ret_base64_blob,
+                char **ret_hex_policy_hash) {
+
+        int r;
+        JsonVariant *w, *e;
+        uint32_t pcr_mask = 0;
+        uint16_t pcr_bank = UINT16_MAX;
+        _cleanup_free_ char *base64_blob = NULL, *hex_policy_hash = NULL;
+        _cleanup_(json_variant_unrefp) JsonVariant *v = NULL;
+
+        assert(json);
+        assert(ret_pcr_mask);
+        assert(ret_pcr_bank);
+        assert(ret_base64_blob);
+        assert(ret_hex_policy_hash);
+
+        r = json_parse(json, 0, &v, NULL, NULL);
+        if (r < 0)
+                return -EINVAL;
+
+        w = json_variant_by_key(v, "tpm2-pcrs");
+        if (!w || !json_variant_is_array(w))
+                return -EINVAL;
+
+        JSON_VARIANT_ARRAY_FOREACH(e, w) {
+                uintmax_t u;
+
+                if (!json_variant_is_number(e))
+                        return -EINVAL;
+
+                u = json_variant_unsigned(e);
+                if (u >= TPM2_PCRS_MAX)
+                        return -EINVAL;
+
+                pcr_mask |= UINT32_C(1) << u;
+        }
+
+        if (search_pcr_mask != UINT32_MAX &&
+            search_pcr_mask != pcr_mask)
+                return -ENXIO;
+
+        w = json_variant_by_key(v, "tpm2-pcr-bank");
+        if (w) {
+                /* The PCR bank field is optional */
+
+                if (!json_variant_is_string(w))
+                        return -EINVAL;
+
+                r = tpm2_pcr_bank_from_string(json_variant_string(w));
+                if (r < 0)
+                        return r;
+
+                pcr_bank = r;
+        }
+
+        w = json_variant_by_key(v, "tpm2-blob");
+        if (!w || !json_variant_is_string(w))
+                return -EINVAL;
+
+        base64_blob = strdup(json_variant_string(w));
+        if (!base64_blob)
+                return -ENOMEM;
+
+        w = json_variant_by_key(v, "tpm2-policy-hash");
+        if (!w || !json_variant_is_string(w))
+                return -EINVAL;
+
+        hex_policy_hash = strdup(json_variant_string(w));
+        if (!hex_policy_hash)
+                return -ENOMEM;
+
+        *ret_pcr_mask = pcr_mask;
+        *ret_pcr_bank = pcr_bank;
+        *ret_base64_blob = TAKE_PTR(base64_blob);
+        *ret_hex_policy_hash = TAKE_PTR(hex_policy_hash);
+
+        return 0;
+}
diff --git a/src/cryptsetup/cryptsetup-tokens/luks2-tpm2.h b/src/cryptsetup/cryptsetup-tokens/luks2-tpm2.h
new file mode 100644 (file)
index 0000000..1a20f2c
--- /dev/null
@@ -0,0 +1,24 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+
+#pragma once
+
+struct crypt_device;
+
+int acquire_luks2_key(
+                uint32_t pcr_mask,
+                uint16_t pcr_bank,
+                const char *device,
+                const void *key_data,
+                size_t key_data_size,
+                const void *policy_hash,
+                size_t policy_hash_size,
+                void **ret_decrypted_key,
+                size_t *ret_decrypted_key_size);
+
+int parse_luks2_tpm2_data(
+                const char *json,
+                uint32_t search_pcr_mask,
+                uint32_t *ret_pcr_mask,
+                uint16_t *ret_pcr_bank,
+                char **ret_base64_blob,
+                char **ret_hex_policy_hash);
diff --git a/src/cryptsetup/cryptsetup-tokens/meson.build b/src/cryptsetup/cryptsetup-tokens/meson.build
new file mode 100644 (file)
index 0000000..7666429
--- /dev/null
@@ -0,0 +1,28 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
+
+if conf.get('HAVE_LIBCRYPTSETUP_PLUGINS') == 1
+
+cryptsetup_token_c_args = ['-fvisibility=hidden']
+
+cryptsetup_token_sym = files('cryptsetup-token.sym')
+cryptsetup_token_sym_path = meson.current_source_dir() / 'cryptsetup-token.sym'
+
+if conf.get('HAVE_TPM2') == 1
+        cryptsetup_token_systemd_tpm2_sources = files('''
+                cryptsetup-token-systemd-tpm2.c
+                cryptsetup-token.h
+                cryptsetup-token-util.h
+                cryptsetup-token-util.c
+                luks2-tpm2.c
+                luks2-tpm2.h
+        '''.split())
+
+        cryptsetup_token_systemd_tpm2_static = static_library(
+                'cryptsetup-token-systemd-tpm2_static',
+                cryptsetup_token_systemd_tpm2_sources,
+                include_directories : includes,
+                dependencies : libshared_deps + [libcryptsetup, versiondep],
+                c_args : cryptsetup_token_c_args)
+endif
+
+endif
index 4757c5882d0e3becbfe14e36e04738809062dc9a..8da1880a35c4d8f75cf9eee93c9c2b144d76405f 100644 (file)
@@ -13,6 +13,7 @@ int acquire_tpm2_key(
                 const char *volume_name,
                 const char *device,
                 uint32_t pcr_mask,
+                uint16_t pcr_bank,
                 const char *key_file,
                 size_t key_file_size,
                 uint64_t key_file_offset,
@@ -62,7 +63,7 @@ int acquire_tpm2_key(
                 blob = loaded_blob;
         }
 
-        return tpm2_unseal(device, pcr_mask, blob, blob_size, policy_hash, policy_hash_size, ret_decrypted_key, ret_decrypted_key_size);
+        return tpm2_unseal(device, pcr_mask, pcr_bank, blob, blob_size, policy_hash, policy_hash_size, ret_decrypted_key, ret_decrypted_key_size);
 }
 
 int find_tpm2_auto_data(
@@ -70,6 +71,7 @@ int find_tpm2_auto_data(
                 uint32_t search_pcr_mask,
                 int start_token,
                 uint32_t *ret_pcr_mask,
+                uint16_t *ret_pcr_bank,
                 void **ret_blob,
                 size_t *ret_blob_size,
                 void **ret_policy_hash,
@@ -81,6 +83,7 @@ int find_tpm2_auto_data(
         size_t blob_size = 0, policy_hash_size = 0;
         int r, keyslot = -1, token = -1;
         uint32_t pcr_mask = 0;
+        uint16_t pcr_bank = UINT16_MAX; /* default: pick automatically */
 
         assert(cd);
 
@@ -119,6 +122,23 @@ int find_tpm2_auto_data(
                     search_pcr_mask != pcr_mask) /* PCR mask doesn't match what is configured, ignore this entry */
                         continue;
 
+                /* The bank field is optional, since it was added in systemd 250 only. Before the bank was hardcoded to SHA256 */
+                assert(pcr_bank == UINT16_MAX);
+                w = json_variant_by_key(v, "tpm2-pcr-bank");
+                if (w) {
+                        /* The PCR bank field is optional */
+
+                        if (!json_variant_is_string(w))
+                                return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
+                                                       "TPM2 PCR bank is not a string.");
+
+                        r = tpm2_pcr_bank_from_string(json_variant_string(w));
+                        if (r < 0)
+                                return log_error_errno(r, "TPM2 PCR bank invalid or not supported: %s", json_variant_string(w));
+
+                        pcr_bank = r;
+                }
+
                 assert(!blob);
                 w = json_variant_by_key(v, "tpm2-blob");
                 if (!w || !json_variant_is_string(w))
@@ -163,6 +183,7 @@ int find_tpm2_auto_data(
         *ret_policy_hash_size = policy_hash_size;
         *ret_keyslot = keyslot;
         *ret_token = token;
+        *ret_pcr_bank = pcr_bank;
 
         return 0;
 }
index 8ddf301a6357101802419a7b3530b6e3eeaa9542..a82ecb459419d819a190d85adbf601a7361b777b 100644 (file)
@@ -13,6 +13,7 @@ int acquire_tpm2_key(
                 const char *volume_name,
                 const char *device,
                 uint32_t pcr_mask,
+                uint16_t pcr_bank,
                 const char *key_file,
                 size_t key_file_size,
                 uint64_t key_file_offset,
@@ -28,6 +29,7 @@ int find_tpm2_auto_data(
                 uint32_t search_pcr_mask,
                 int start_token,
                 uint32_t *ret_pcr_mask,
+                uint16_t *ret_pcr_bank,
                 void **ret_blob,
                 size_t *ret_blob_size,
                 void **ret_policy_hash,
@@ -41,6 +43,7 @@ static inline int acquire_tpm2_key(
                 const char *volume_name,
                 const char *device,
                 uint32_t pcr_mask,
+                uint16_t pcr_bank,
                 const char *key_file,
                 size_t key_file_size,
                 uint64_t key_file_offset,
@@ -60,6 +63,7 @@ static inline int find_tpm2_auto_data(
                 uint32_t search_pcr_mask,
                 int start_token,
                 uint32_t *ret_pcr_mask,
+                uint16_t *ret_pcr_bank,
                 void **ret_blob,
                 size_t *ret_blob_size,
                 void **ret_policy_hash,
index 0fa41b836028b3bcd8b482951a21021c4d052686..0d3ea9cda647edabaf67077ea9bad9457a73f4ca 100644 (file)
@@ -453,7 +453,6 @@ static char* disk_description(const char *path) {
         _cleanup_(sd_device_unrefp) sd_device *device = NULL;
         const char *i, *name;
         struct stat st;
-        int r;
 
         assert(path);
 
@@ -468,14 +467,15 @@ static char* disk_description(const char *path) {
 
         if (sd_device_get_property_value(device, "ID_PART_ENTRY_NAME", &name) >= 0) {
                 _cleanup_free_ char *unescaped = NULL;
+                ssize_t l;
 
                 /* ID_PART_ENTRY_NAME uses \x style escaping, using libblkid's blkid_encode_string(). Let's
                  * reverse this here to make the string more human friendly in case people embed spaces or
                  * other weird stuff. */
 
-                r = cunescape(name, UNESCAPE_RELAX, &unescaped);
-                if (r < 0) {
-                        log_debug_errno(r, "Failed to unescape ID_PART_ENTRY_NAME, skipping device: %m");
+                l = cunescape(name, UNESCAPE_RELAX, &unescaped);
+                if (l < 0) {
+                        log_debug_errno(l, "Failed to unescape ID_PART_ENTRY_NAME, skipping device: %m");
                         return NULL;
                 }
 
@@ -1041,6 +1041,33 @@ static int make_tpm2_device_monitor(sd_event *event, sd_device_monitor **ret) {
         return 0;
 }
 
+static int attach_luks2_by_tpm2(
+                struct crypt_device *cd,
+                const char *name,
+                uint32_t flags) {
+
+#if HAVE_LIBCRYPTSETUP_PLUGINS
+        int r;
+
+        systemd_tpm2_plugin_params params = {
+                .search_pcr_mask = arg_tpm2_pcr_mask,
+                .device = arg_tpm2_device
+        };
+
+        if (crypt_token_external_path() == NULL)
+                return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP),
+                                       "Libcryptsetup has external plugins support disabled.");
+
+        r = crypt_activate_by_token_pin(cd, name, "systemd-tpm2", CRYPT_ANY_TOKEN, NULL, 0, &params, flags);
+        if (r > 0) /* returns unlocked keyslot id on success */
+                r = 0;
+
+        return r;
+#else
+        return -EOPNOTSUPP;
+#endif
+}
+
 static int attach_luks_or_plain_or_bitlk_by_tpm2(
                 struct crypt_device *cd,
                 const char *name,
@@ -1076,6 +1103,7 @@ static int attach_luks_or_plain_or_bitlk_by_tpm2(
                                         name,
                                         arg_tpm2_device,
                                         arg_tpm2_pcr_mask == UINT32_MAX ? TPM2_PCR_MASK_DEFAULT : arg_tpm2_pcr_mask,
+                                        UINT16_MAX,
                                         key_file, arg_keyfile_size, arg_keyfile_offset,
                                         key_data, key_data_size,
                                         NULL, 0, /* we don't know the policy hash */
@@ -1087,6 +1115,20 @@ static int attach_luks_or_plain_or_bitlk_by_tpm2(
                         if (r != -EAGAIN) /* EAGAIN means: no tpm2 chip found */
                                 return r;
                 } else {
+                        r = attach_luks2_by_tpm2(cd, name, flags);
+                        /* EAGAIN     means: no tpm2 chip found
+                         * EOPNOTSUPP means: no libcryptsetup plugins support */
+                        if (r == -ENXIO)
+                                return log_debug_errno(SYNTHETIC_ERRNO(EAGAIN),
+                                                       "No TPM2 metadata matching the current system state found in LUKS2 header, falling back to traditional unlocking.");
+                        if (r == -ENOENT)
+                                return log_debug_errno(SYNTHETIC_ERRNO(EAGAIN),
+                                                       "No TPM2 metadata enrolled in LUKS2 header or TPM2 support not available, falling back to traditional unlocking.");
+                        if (!IN_SET(r, -EOPNOTSUPP, -EAGAIN))
+                                return r;
+                }
+
+                if (r == -EOPNOTSUPP) {
                         _cleanup_free_ void *blob = NULL, *policy_hash = NULL;
                         size_t blob_size, policy_hash_size;
                         bool found_some = false;
@@ -1098,12 +1140,14 @@ static int attach_luks_or_plain_or_bitlk_by_tpm2(
 
                         for (;;) {
                                 uint32_t pcr_mask;
+                                uint16_t pcr_bank;
 
                                 r = find_tpm2_auto_data(
                                                 cd,
                                                 arg_tpm2_pcr_mask, /* if != UINT32_MAX we'll only look for tokens with this PCR mask */
                                                 token, /* search for the token with this index, or any later index than this */
                                                 &pcr_mask,
+                                                &pcr_bank,
                                                 &blob, &blob_size,
                                                 &policy_hash, &policy_hash_size,
                                                 &keyslot,
@@ -1125,6 +1169,7 @@ static int attach_luks_or_plain_or_bitlk_by_tpm2(
                                                 name,
                                                 arg_tpm2_device,
                                                 pcr_mask,
+                                                pcr_bank,
                                                 NULL, 0, 0, /* no key file */
                                                 blob, blob_size,
                                                 policy_hash, policy_hash_size,
index f78c6b9c0d3ee8c549e966f84804e14ab0cf6d90..282168a584ccb8de0ddc6ba11038e9fb3d54a2e7 100644 (file)
@@ -625,7 +625,7 @@ static int parse_argv(int argc, char *argv[]) {
                         return -EINVAL;
 
                 default:
-                        assert_not_reached("Unhandled option");
+                        assert_not_reached();
                 }
 
         return 1;
index bfdede6ce7a5c05fe0697caaa1649a4366016791..d284fcbe82abac98460c8b6211d2e88873836147 100644 (file)
@@ -109,7 +109,7 @@ static int parse_argv(int argc, char *argv[]) {
                         return -EINVAL;
 
                 default:
-                        assert_not_reached("Unhandled option");
+                        assert_not_reached();
                 }
 
         if (optind < argc)
index 47feba3d627119dd9bbf3b89412f19ae9b9a8f2a..68c8bedc9b0e2474b84c1a3ec7907b64c2d179ce 100644 (file)
@@ -287,7 +287,7 @@ static int parse_argv(int argc, char *argv[]) {
                         return -EINVAL;
 
                 default:
-                        assert_not_reached("Unhandled option");
+                        assert_not_reached();
                 }
 
         }
@@ -344,7 +344,7 @@ static int parse_argv(int argc, char *argv[]) {
                 break;
 
         default:
-                assert_not_reached("Unknown action.");
+                assert_not_reached();
         }
 
         return 1;
@@ -385,10 +385,8 @@ static int action_dissect(DissectedImage *m, LoopDevice *d) {
 
         if (ioctl(d->fd, BLKGETSIZE64, &size) < 0)
                 log_debug_errno(errno, "Failed to query size of loopback device: %m");
-        else if (arg_json_format_flags & JSON_FORMAT_OFF) {
-                char s[FORMAT_BYTES_MAX];
-                printf("      Size: %s\n", format_bytes(s, sizeof(s), size));
-        }
+        else if (arg_json_format_flags & JSON_FORMAT_OFF)
+                printf("      Size: %s\n", FORMAT_BYTES(size));
 
         if (arg_json_format_flags & JSON_FORMAT_OFF)
                 putc('\n', stdout);
@@ -820,7 +818,7 @@ static int run(int argc, char *argv[]) {
                 break;
 
         default:
-                assert_not_reached("Unknown action.");
+                assert_not_reached();
         }
 
         return r;
index 1575a684107709170c93c7924ca59210c02caeb4..167305cb03322fe151b27b70438b48a6d9dd1cf4 100644 (file)
@@ -119,7 +119,7 @@ static int parse_argv(int argc, char *argv[]) {
                         return -EINVAL;
 
                 default:
-                        assert_not_reached("Unhandled option");
+                        assert_not_reached();
                 }
 
         if (optind >= argc)
index 2cb4f80d5d5d9a00398a2f6a0023908811b3ebfb..0a055c21c9ccac4dd6fe8311888b43bbb8eb2268 100644 (file)
@@ -1299,7 +1299,7 @@ static int parse_argv(int argc, char *argv[]) {
                         return -EINVAL;
 
                 default:
-                        assert_not_reached("Unhandled option");
+                        assert_not_reached();
                 }
 
         /* We check if the specified locale strings are valid down here, so that we can take --root= into
index a4e3ea531101a485d4f14c589de0be830274a443..bafc7b8f960bb5d2a75dbeea1d8edc1cd6166471 100644 (file)
@@ -196,7 +196,6 @@ static int write_timeout(
                 const char *variable) {
 
         _cleanup_free_ char *timeout = NULL;
-        char timespan[FORMAT_TIMESPAN_MAX];
         usec_t u;
         int r;
 
@@ -212,7 +211,7 @@ static int write_timeout(
                 return 0;
         }
 
-        fprintf(f, "%s=%s\n", variable, format_timespan(timespan, sizeof(timespan), u, 0));
+        fprintf(f, "%s=%s\n", variable, FORMAT_TIMESPAN(u, 0));
 
         return 0;
 }
index 967518600d404db52ad232d87789302899f2ff21..e9fb4d393804b2933c4460bd04efa2743f24abe4 100644 (file)
                 UNIQ_T(A, aq) > UNIQ_T(B, bq) ? UNIQ_T(A, aq) : UNIQ_T(B, bq); \
         })
 
-/* evaluates to (void) if _A or _B are not constant or of different types */
+#define IS_UNSIGNED_INTEGER_TYPE(type) \
+        (__builtin_types_compatible_p(typeof(type), unsigned char) ||   \
+         __builtin_types_compatible_p(typeof(type), unsigned short) ||  \
+         __builtin_types_compatible_p(typeof(type), unsigned) ||        \
+         __builtin_types_compatible_p(typeof(type), unsigned long) ||   \
+         __builtin_types_compatible_p(typeof(type), unsigned long long))
+
+#define IS_SIGNED_INTEGER_TYPE(type) \
+        (__builtin_types_compatible_p(typeof(type), signed char) ||   \
+         __builtin_types_compatible_p(typeof(type), signed short) ||  \
+         __builtin_types_compatible_p(typeof(type), signed) ||        \
+         __builtin_types_compatible_p(typeof(type), signed long) ||   \
+         __builtin_types_compatible_p(typeof(type), signed long long))
+
+/* Evaluates to (void) if _A or _B are not constant or of different types (being integers of different sizes
+ * is also OK as long as the signedness matches) */
 #define CONST_MAX(_A, _B) \
         (__builtin_choose_expr(                                         \
                 __builtin_constant_p(_A) &&                             \
                 __builtin_constant_p(_B) &&                             \
-                __builtin_types_compatible_p(typeof(_A), typeof(_B)),   \
+                (__builtin_types_compatible_p(typeof(_A), typeof(_B)) || \
+                 (IS_UNSIGNED_INTEGER_TYPE(_A) && IS_UNSIGNED_INTEGER_TYPE(_B)) || \
+                 (IS_SIGNED_INTEGER_TYPE(_A) && IS_SIGNED_INTEGER_TYPE(_B))), \
                 ((_A) > (_B)) ? (_A) : (_B),                            \
                 VOID_0))
 
index 40b9ab8e2cd3d02e904090fb846e1c0289aaac42..3c43081cf61d54f1c0d68b9653cd303b46d0174e 100644 (file)
@@ -14,8 +14,8 @@ sources = '''
 
 # for sd-boot
 fundamental_source_paths = []
-foreach s : sources
-        fundamental_source_paths += join_paths(meson.current_source_dir(), s)
+foreach source : sources
+        fundamental_source_paths += meson.current_source_dir() / source
 endforeach
 
 # for libbasic
index 6273cb6c90693bf09c57cdad0019d01590e08069..d3dbf2d534c13fec0959d91db4d1ddde7372e37c 100644 (file)
@@ -3463,7 +3463,7 @@ static int parse_argv(int argc, char *argv[]) {
                         return -EINVAL;
 
                 default:
-                        assert_not_reached("Unhandled option");
+                        assert_not_reached();
                 }
         }
 
index 104427dabe8a938eb47f85b0e0240f2a0a875987..351b88df4e9c16077a1e48c7d64ef7a7f45a6177 100644 (file)
@@ -957,7 +957,7 @@ static int home_on_worker_process(sd_event_source *s, const siginfo_t *si, void
                 break;
 
         default:
-                assert_not_reached("Unexpected state after worker exited");
+                assert_not_reached();
         }
 
         return 0;
@@ -1097,15 +1097,15 @@ static int home_ratelimit(Home *h, sd_bus_error *error) {
         }
 
         if (ret == 0) {
-                char buf[FORMAT_TIMESPAN_MAX];
                 usec_t t, n;
 
                 n = now(CLOCK_REALTIME);
                 t = user_record_ratelimit_next_try(h->record);
 
                 if (t != USEC_INFINITY && t > n)
-                        return sd_bus_error_setf(error, BUS_ERROR_AUTHENTICATION_LIMIT_HIT, "Too many login attempts, please try again in %s!",
-                                                 format_timespan(buf, sizeof(buf), t - n, USEC_PER_SEC));
+                        return sd_bus_error_setf(error, BUS_ERROR_AUTHENTICATION_LIMIT_HIT,
+                                                 "Too many login attempts, please try again in %s!",
+                                                 FORMAT_TIMESPAN(t - n, USEC_PER_SEC));
 
                 return sd_bus_error_set(error, BUS_ERROR_AUTHENTICATION_LIMIT_HIT, "Too many login attempts, please try again later.");
         }
index b25542638250ffdc32eeae062808b03db0f9cf88..6549e6bd4ef24b46988729e74a34927b6b3ee38d 100644 (file)
@@ -597,7 +597,7 @@ static int manager_acquire_uid(
                         break;
 
                 default:
-                        assert_not_reached("unknown phase");
+                        assert_not_reached();
                 }
 
                 other = hashmap_get(m->homes_by_uid, UID_TO_PTR(candidate));
index b35d24c85a09e012b8c2a0dbdb08885d77ef6451..45a2fb9db78b72467b26f84b845b7b799033a34d 100644 (file)
@@ -141,7 +141,7 @@ int home_create_directory_or_subvolume(UserRecord *h, UserRecord **ret_home) {
                 break;
 
         default:
-                assert_not_reached("unexpected storage");
+                assert_not_reached();
         }
 
         temporary = TAKE_PTR(d); /* Needs to be destroyed now */
index 6448883fe0455d1e6ea368a34bc8112b67038d3b..3d4361c4ecfa705e33f28aca4dce694cdd4c7f9b 100644 (file)
@@ -949,7 +949,6 @@ int home_store_header_identity_luks(
 }
 
 int run_fitrim(int root_fd) {
-        char buf[FORMAT_BYTES_MAX];
         struct fstrim_range range = {
                 .len = UINT64_MAX,
         };
@@ -968,8 +967,7 @@ int run_fitrim(int root_fd) {
                 return log_warning_errno(errno, "Failed to invoke FITRIM, ignoring: %m");
         }
 
-        log_info("Discarded unused %s.",
-                 format_bytes(buf, sizeof(buf), range.len));
+        log_info("Discarded unused %s.", FORMAT_BYTES(range.len));
         return 1;
 }
 
@@ -984,7 +982,6 @@ int run_fitrim_by_path(const char *root_path) {
 }
 
 int run_fallocate(int backing_fd, const struct stat *st) {
-        char buf[FORMAT_BYTES_MAX];
         struct stat stbuf;
 
         assert(backing_fd >= 0);
@@ -1023,7 +1020,7 @@ int run_fallocate(int backing_fd, const struct stat *st) {
         }
 
         log_info("Allocated additional %s.",
-                 format_bytes(buf, sizeof(buf), (DIV_ROUND_UP(st->st_size, 512) - st->st_blocks) * 512));
+                 FORMAT_BYTES((DIV_ROUND_UP(st->st_size, 512) - st->st_blocks) * 512));
         return 1;
 }
 
@@ -1278,15 +1275,13 @@ fail:
 }
 
 static void print_size_summary(uint64_t host_size, uint64_t encrypted_size, struct statfs *sfs) {
-        char buffer1[FORMAT_BYTES_MAX], buffer2[FORMAT_BYTES_MAX], buffer3[FORMAT_BYTES_MAX], buffer4[FORMAT_BYTES_MAX];
-
         assert(sfs);
 
         log_info("Image size is %s, file system size is %s, file system payload size is %s, file system free is %s.",
-                 format_bytes(buffer1, sizeof(buffer1), host_size),
-                 format_bytes(buffer2, sizeof(buffer2), encrypted_size),
-                 format_bytes(buffer3, sizeof(buffer3), (uint64_t) sfs->f_blocks * (uint64_t) sfs->f_frsize),
-                 format_bytes(buffer4, sizeof(buffer4), (uint64_t) sfs->f_bfree * (uint64_t) sfs->f_frsize));
+                 FORMAT_BYTES(host_size),
+                 FORMAT_BYTES(encrypted_size),
+                 FORMAT_BYTES((uint64_t) sfs->f_blocks * (uint64_t) sfs->f_frsize),
+                 FORMAT_BYTES((uint64_t) sfs->f_bfree * (uint64_t) sfs->f_frsize));
 }
 
 int home_activate_luks(
@@ -1793,7 +1788,6 @@ static int wait_for_devlink(const char *path) {
 }
 
 static int calculate_disk_size(UserRecord *h, const char *parent_dir, uint64_t *ret) {
-        char buf[FORMAT_BYTES_MAX];
         struct statfs sfs;
         uint64_t m;
 
@@ -1820,14 +1814,14 @@ static int calculate_disk_size(UserRecord *h, const char *parent_dir, uint64_t *
 
                 log_info("Sizing home to %u%% of available disk space, which is %s.",
                          USER_DISK_SIZE_DEFAULT_PERCENT,
-                         format_bytes(buf, sizeof(buf), *ret));
+                         FORMAT_BYTES(*ret));
         } else {
                 *ret = DISK_SIZE_ROUND_DOWN((uint64_t) ((double) m * (double) h->disk_size_relative / (double) UINT32_MAX));
 
                 log_info("Sizing home to %" PRIu64 ".%01" PRIu64 "%% of available disk space, which is %s.",
                          (h->disk_size_relative * 100) / UINT32_MAX,
                          ((h->disk_size_relative * 1000) / UINT32_MAX) % 10,
-                         format_bytes(buf, sizeof(buf), *ret));
+                         FORMAT_BYTES(*ret));
         }
 
         if (*ret < USER_DISK_SIZE_MIN)
@@ -2631,8 +2625,6 @@ int home_resize_luks(
                 HomeSetup *setup,
                 UserRecord **ret_home) {
 
-        char buffer1[FORMAT_BYTES_MAX], buffer2[FORMAT_BYTES_MAX], buffer3[FORMAT_BYTES_MAX],
-                buffer4[FORMAT_BYTES_MAX], buffer5[FORMAT_BYTES_MAX], buffer6[FORMAT_BYTES_MAX];
         uint64_t old_image_size, new_image_size, old_fs_size, new_fs_size, crypto_offset, new_partition_size;
         _cleanup_(user_record_unrefp) UserRecord *header_home = NULL, *embedded_home = NULL, *new_home = NULL;
         _cleanup_(fdisk_unref_tablep) struct fdisk_table *table = NULL;
@@ -2770,12 +2762,12 @@ int home_resize_luks(
                 return log_error_errno(SYNTHETIC_ERRNO(ETXTBSY), "File systems of this type can only be resized offline, but is currently online.");
 
         log_info("Ready to resize image size %s → %s, partition size %s → %s, file system size %s → %s.",
-                 format_bytes(buffer1, sizeof(buffer1), old_image_size),
-                 format_bytes(buffer2, sizeof(buffer2), new_image_size),
-                 format_bytes(buffer3, sizeof(buffer3), setup->partition_size),
-                 format_bytes(buffer4, sizeof(buffer4), new_partition_size),
-                 format_bytes(buffer5, sizeof(buffer5), old_fs_size),
-                 format_bytes(buffer6, sizeof(buffer6), new_fs_size));
+                 FORMAT_BYTES(old_image_size),
+                 FORMAT_BYTES(new_image_size),
+                 FORMAT_BYTES(setup->partition_size),
+                 FORMAT_BYTES(new_partition_size),
+                 FORMAT_BYTES(old_fs_size),
+                 FORMAT_BYTES(new_fs_size));
 
         r = prepare_resize_partition(
                         image_fd,
index bdd9ac649e53a7bdc6da5edffa5752b7460b0ef3..ee1d4068bad92779eadd5ee3ade372b66da5eb96 100644 (file)
@@ -791,7 +791,7 @@ static int home_activate(UserRecord *h, UserRecord **ret_home) {
                 break;
 
         default:
-                assert_not_reached("unexpected type");
+                assert_not_reached();
         }
 
         /* Note that the returned object might either be a reference to an updated version of the existing
@@ -1305,7 +1305,7 @@ static int home_remove(UserRecord *h) {
                 break;
 
         default:
-                assert_not_reached("unknown storage type");
+                assert_not_reached();
         }
 
         if (hd) {
@@ -1370,7 +1370,7 @@ static int home_validate_update(UserRecord *h, HomeSetup *setup) {
         }
 
         default:
-                assert_not_reached("unexpected storage type");
+                assert_not_reached();
         }
 
         return has_mount; /* return true if the home record is already active */
index b7db39dab9cc9d271b31f3ff2bd9a3beb0c9e1a6..836ed0d5e96dda39259002211bace05010e76ab5 100644 (file)
@@ -892,9 +892,8 @@ _public_ PAM_EXTERN int pam_sm_acct_mgmt(
                 usec_t n = now(CLOCK_REALTIME);
 
                 if (t > n) {
-                        char buf[FORMAT_TIMESPAN_MAX];
                         (void) pam_prompt(handle, PAM_ERROR_MSG, NULL, "Too many logins, try again in %s.",
-                                          format_timespan(buf, sizeof(buf), t - n, USEC_PER_SEC));
+                                          FORMAT_TIMESPAN(t - n, USEC_PER_SEC));
 
                         return PAM_MAXTRIES;
                 }
index b5ed6b1689500c53c16376bb55cfe6571813dafe..ef8e18de61490e4471c3d805f0b00e4c995715b0 100644 (file)
@@ -544,7 +544,7 @@ int user_record_test_image_path(UserRecord *h) {
                 return -ENOTDIR;
 
         default:
-                assert_not_reached("Unexpected record type");
+                assert_not_reached();
         }
 }
 
index 283038c7cbaf55e5dc3d96122400df543803588c..bc780701314e13f3b4b298c1dd1208013d679aea 100644 (file)
@@ -620,7 +620,7 @@ static int parse_argv(int argc, char *argv[]) {
                         return -EINVAL;
 
                 default:
-                        assert_not_reached("Unhandled option");
+                        assert_not_reached();
                 }
 
         return 1;
index 26cc83f31bd57249bf5cc3bf7d63f64195e6e270..e2144df62cb9aa504b9c0d5f52b1adbe49c6d1c8 100644 (file)
@@ -98,7 +98,7 @@ static int parse_argv(int argc, char *argv[]) {
                         return -EINVAL;
 
                 default:
-                        assert_not_reached("Unknown option");
+                        assert_not_reached();
                 }
 
         return 1;
index 435a56d4f34de47a5bcdf139ff29cec20d984923..89b944f8c037afb6ef605082c44553ce5ae62e34 100644 (file)
@@ -226,7 +226,7 @@ static int parse_argv(int argc, char *argv[]) {
                         return -EINVAL;
 
                 default:
-                        assert_not_reached("Unhandled option");
+                        assert_not_reached();
                 }
 
         return 1;
index a4f3f6c38e073402ab28dfe622d0cbccc347cbd2..26533baeb89a11e5a7e42c4823c06ed3b568112c 100644 (file)
@@ -261,7 +261,7 @@ static int parse_argv(int argc, char *argv[]) {
                         return -EINVAL;
 
                 default:
-                        assert_not_reached("Unhandled option");
+                        assert_not_reached();
                 }
 
         return 1;
index aa837af5659b61d0b29a47b4eb43454627ccfbf4..03f5efa00ec6ee4e789806de547d03f4572303e0 100644 (file)
@@ -190,7 +190,7 @@ int import_uncompress(ImportCompress *c, const void *data, size_t size, ImportCo
 #endif
 
         default:
-                assert_not_reached("Unknown compression");
+                assert_not_reached();
         }
 
         return 1;
index a12ee77ef9fc7fb6bdc85ad9d15ed85d7449b4a3..88bfe2997020b7d3f3e9582a0b2561469e2f2ef0 100644 (file)
@@ -62,11 +62,8 @@ static void progress_show(ProgressInfo *p) {
 
         if (p->size == 0)
                 log_info("Copying tree, currently at '%s'...", p->path);
-        else {
-                char buffer[FORMAT_BYTES_MAX];
-
-                log_info("Copying tree, currently at '%s' (@%s)...", p->path, format_bytes(buffer, sizeof(buffer), p->size));
-        }
+        else
+                log_info("Copying tree, currently at '%s' (@%s)...", p->path, FORMAT_BYTES(p->size));
 }
 
 static int progress_path(const char *path, const struct stat *st, void *userdata) {
@@ -293,7 +290,7 @@ static int parse_argv(int argc, char *argv[]) {
                         return -EINVAL;
 
                 default:
-                        assert_not_reached("Unhandled option");
+                        assert_not_reached();
                 }
 
         return 1;
index fe4c03a4da52f7972e1cb261d30b6f9bc4b9a0be..cc90732d7188dca0aa1d413c7ed25192aaffe792 100644 (file)
@@ -278,7 +278,7 @@ static int parse_argv(int argc, char *argv[]) {
                         return -EINVAL;
 
                 default:
-                        assert_not_reached("Unhandled option");
+                        assert_not_reached();
                 }
 
         return 1;
index f0f61ca7848e62153b5dad7f5bcb450615147c6e..0a870568194d8453dde4722fc4afc65988c06978 100644 (file)
@@ -431,7 +431,7 @@ static int transfer_start(Transfer *t) {
                         break;
 
                 default:
-                        assert_not_reached("Unexpected transfer type");
+                        assert_not_reached();
                 }
 
                 switch (t->type) {
index 75c5c7493ec4d7f3cb2395fceefefcd73f2232ce..cb77454e0f6983015e216fd1f94601828548c31d 100644 (file)
@@ -34,10 +34,6 @@ int pull_find_old_etags(
                 const char *suffix,
                 char ***etags) {
 
-        _cleanup_free_ char *escaped_url = NULL;
-        _cleanup_closedir_ DIR *d = NULL;
-        _cleanup_strv_free_ char **l = NULL;
-        struct dirent *de;
         int r;
 
         assert(url);
@@ -46,11 +42,11 @@ int pull_find_old_etags(
         if (!image_root)
                 image_root = "/var/lib/machines";
 
-        escaped_url = xescape(url, FILENAME_ESCAPE);
+        _cleanup_free_ char *escaped_url = xescape(url, FILENAME_ESCAPE);
         if (!escaped_url)
                 return -ENOMEM;
 
-        d = opendir(image_root);
+        _cleanup_closedir_ DIR *d = opendir(image_root);
         if (!d) {
                 if (errno == ENOENT) {
                         *etags = NULL;
@@ -60,6 +56,9 @@ int pull_find_old_etags(
                 return -errno;
         }
 
+        _cleanup_strv_free_ char **ans = NULL;
+        struct dirent *de;
+
         FOREACH_DIRENT_ALL(de, d, return -errno) {
                 _cleanup_free_ char *u = NULL;
                 const char *a, *b;
@@ -93,19 +92,21 @@ int pull_find_old_etags(
                 if (a >= b)
                         continue;
 
-                r = cunescape_length(a, b - a, 0, &u);
-                if (r < 0)
-                        return r;
+                ssize_t l = cunescape_length(a, b - a, 0, &u);
+                if (l < 0) {
+                        assert(l >= INT8_MIN);
+                        return l;
+                }
 
                 if (!http_etag_is_valid(u))
                         continue;
 
-                r = strv_consume(&l, TAKE_PTR(u));
+                r = strv_consume(&ans, TAKE_PTR(u));
                 if (r < 0)
                         return r;
         }
 
-        *etags = TAKE_PTR(l);
+        *etags = TAKE_PTR(ans);
 
         return 0;
 }
index 9ab3776e506a1d9383593d31a8ae721937b961d9..e751d3af05962fbc746181df46a4cbc308b512d6 100644 (file)
@@ -421,7 +421,7 @@ static size_t pull_job_write_callback(void *contents, size_t size, size_t nmemb,
                 goto fail;
 
         default:
-                assert_not_reached("Impossible state.");
+                assert_not_reached();
         }
 
         return sz;
@@ -501,15 +501,12 @@ static size_t pull_job_header_callback(void *contents, size_t size, size_t nmemb
                 (void) safe_atou64(length, &j->content_length);
 
                 if (j->content_length != UINT64_MAX) {
-                        char bytes[FORMAT_BYTES_MAX];
-
                         if (j->content_length > j->compressed_max) {
-                                log_error("Content too large.");
-                                r = -EFBIG;
+                                r = log_error_errno(SYNTHETIC_ERRNO(EFBIG), "Content too large.");
                                 goto fail;
                         }
 
-                        log_info("Downloading %s for %s.", format_bytes(bytes, sizeof(bytes), j->content_length), j->url);
+                        log_info("Downloading %s for %s.", FORMAT_BYTES(j->content_length), j->url);
                 }
 
                 return sz;
@@ -554,10 +551,8 @@ static int pull_job_progress_callback(void *userdata, curl_off_t dltotal, curl_o
         if (n > j->last_status_usec + USEC_PER_SEC &&
             percent != j->progress_percent &&
             dlnow < dltotal) {
-                char buf[FORMAT_TIMESPAN_MAX];
 
                 if (n - j->start_usec > USEC_PER_SEC && dlnow > 0) {
-                        char y[FORMAT_BYTES_MAX];
                         usec_t left, done;
 
                         done = n - j->start_usec;
@@ -566,8 +561,8 @@ static int pull_job_progress_callback(void *userdata, curl_off_t dltotal, curl_o
                         log_info("Got %u%% of %s. %s left at %s/s.",
                                  percent,
                                  j->url,
-                                 format_timespan(buf, sizeof(buf), left, USEC_PER_SEC),
-                                 format_bytes(y, sizeof(y), (uint64_t) ((double) dlnow / ((double) done / (double) USEC_PER_SEC))));
+                                 FORMAT_TIMESPAN(left, USEC_PER_SEC),
+                                 FORMAT_BYTES((uint64_t) ((double) dlnow / ((double) done / (double) USEC_PER_SEC))));
                 } else
                         log_info("Got %u%% of %s.", percent, j->url);
 
index 9b5d8ef9e30c009e96b40f9273f5ec30a0a0612f..ca4f2502101754d5fbb5d616b903b8ff3200b82b 100644 (file)
@@ -222,7 +222,7 @@ static void raw_pull_report_progress(RawPull *i, RawProgress p) {
                 break;
 
         default:
-                assert_not_reached("Unknown progress state");
+                assert_not_reached();
         }
 
         sd_notifyf(false, "X_IMPORT_PROGRESS=%u", percent);
index a2ba56df2f39262a67fe6f1b9c757bc8d54c98ce..1227c89ffb1c28935bf7672c4ac88c38a50bae50 100644 (file)
@@ -187,7 +187,7 @@ static void tar_pull_report_progress(TarPull *i, TarProgress p) {
                 break;
 
         default:
-                assert_not_reached("Unknown progress state");
+                assert_not_reached();
         }
 
         sd_notifyf(false, "X_IMPORT_PROGRESS=%u", percent);
index d24c71b00ecf530d4173306ab91edd1c6797b34c..17ade56c2a0486f7fa26f92f0198c0d65bfaaef5 100644 (file)
@@ -321,7 +321,7 @@ static int parse_argv(int argc, char *argv[]) {
                         return -EINVAL;
 
                 default:
-                        assert_not_reached("Unhandled option");
+                        assert_not_reached();
                 }
 
         return 1;
index ab1cf7b109673349d170f6bb7ca45ba2a7c2e275..38972fe1a96ff164ad418212dd098585bb79aee4 100644 (file)
@@ -992,7 +992,7 @@ static int parse_argv(int argc, char *argv[]) {
                         return -EINVAL;
 
                 default:
-                        assert_not_reached("Unhandled option");
+                        assert_not_reached();
                 }
 
         if (optind < argc)
index ae1d43756a143ede25b95ad2b2d000681e6f034a..140ecac2073deabd34e364bb90feca5ad272382f 100644 (file)
@@ -1003,7 +1003,7 @@ static int parse_argv(int argc, char *argv[]) {
                         return -EINVAL;
 
                 default:
-                        assert_not_reached("Unknown option code.");
+                        assert_not_reached();
                 }
 
         if (optind < argc)
index 6e5aebdc485704f110b64058055f0779dfa7f496..9c1ee0188dd334f68cd5b22395ea4627922a5e1a 100644 (file)
@@ -58,7 +58,7 @@ static int open_output(RemoteServer *s, Writer *w, const char* host) {
         }
 
         default:
-                assert_not_reached("what?");
+                assert_not_reached();
         }
 
         r = journal_file_open_reliably(filename,
@@ -110,7 +110,7 @@ int journal_remote_get_writer(RemoteServer *s, const char *host, Writer **writer
                 break;
 
         default:
-                assert_not_reached("what split mode?");
+                assert_not_reached();
         }
 
         w = hashmap_get(s->writers, key);
@@ -323,7 +323,7 @@ int journal_remote_server_init(
         else if (split_mode == JOURNAL_WRITE_SPLIT_HOST)
                 s->output = REMOTE_JOURNAL_PATH;
         else
-                assert_not_reached("bad split mode");
+                assert_not_reached();
 
         r = sd_event_default(&s->events);
         if (r < 0)
index f23d5cf8b9ca6d9a2edc2fe85393e1d0f569b220..899f47eea4354e44c38249b2f46a639c357572c9 100644 (file)
@@ -229,10 +229,10 @@ static ssize_t write_entry(char *buf, size_t size, Uploader *u) {
                         return pos;
 
                 default:
-                        assert_not_reached("WTF?");
+                        assert_not_reached();
                 }
         }
-        assert_not_reached("WTF?");
+        assert_not_reached();
 }
 
 static void check_update_watchdog(Uploader *u) {
index 2a38d206ea16aa3c01ebb4e9a86befa71c1a05c2..3c28bbab7a20c5424b7f75f63c4f70d17d35959f 100644 (file)
@@ -779,7 +779,7 @@ static int parse_argv(int argc, char *argv[]) {
                                                argv[optind - 1]);
 
                 default:
-                        assert_not_reached("Unhandled option code.");
+                        assert_not_reached();
                 }
 
         if (!arg_url)
index 6e42d8a8b46b9c74efd0d49db5beb75f5f8bdb74..2843afb4c93c7c7df90b8832c402b49a10851495 100755 (executable)
@@ -32,10 +32,6 @@ _SOURCE_REALTIME_TIMESTAMP={source_realtime_ts}
 DATA={data}
 """
 
-m = 0x198603b12d7
-realtime_ts = 1404101101501873
-monotonic_ts = 1753961140951
-source_realtime_ts = 1404101101483516
 priority = 3
 facility = 6
 
@@ -55,18 +51,14 @@ for i in range(OPTIONS.n):
         data = '{:0{}}'.format(counter, OPTIONS.data_size)
         counter += 1
 
-    entry = template.format(m=m,
-                            realtime_ts=realtime_ts,
-                            monotonic_ts=monotonic_ts,
-                            source_realtime_ts=source_realtime_ts,
+    entry = template.format(m=0x198603b12d7 + i,
+                            realtime_ts=1404101101501873 + i,
+                            monotonic_ts=1753961140951 + i,
+                            source_realtime_ts=1404101101483516 + i,
                             priority=priority,
                             facility=facility,
                             message=message,
                             data=data)
-    m += 1
-    realtime_ts += 1
-    monotonic_ts += 1
-    source_realtime_ts += 1
 
     bytes += len(entry)
 
index d516fbabf7b8fdc536aa3fdcc8bd26707c8ec754..5670d55ec5502e88711ea7d9295a5d305cac2e38 100644 (file)
@@ -62,7 +62,7 @@ endforeach
 
 if conf.get('ENABLE_REMOTE') == 1 and conf.get('HAVE_MICROHTTPD') == 1
         install_data('browse.html',
-                     install_dir : join_paths(pkgdatadir, 'gatewayd'))
+                     install_dir : pkgdatadir / 'gatewayd')
 
         if get_option('create-log-dirs')
                 meson.add_install_script('sh', '-c',
index 4ccc5e0a330aab3922939206aaa6f20cc680f9e1..0c2c0d6152d113de3c5d53d1e63f5396e47bf481 100644 (file)
@@ -115,7 +115,7 @@ static int parse_argv(int argc, char *argv[]) {
                         return -EINVAL;
 
                 default:
-                        assert_not_reached("Unhandled option");
+                        assert_not_reached();
                 }
 
         return 1;
index 17fc493b22fa6200515d2ce48a648b3a21c30fd7..15c72d5d35b25dab7bfe899e2eb32c4ed26e7a82 100644 (file)
@@ -1046,7 +1046,7 @@ static int parse_argv(int argc, char *argv[]) {
                         return -EINVAL;
 
                 default:
-                        assert_not_reached("Unhandled option");
+                        assert_not_reached();
                 }
 
         if (arg_follow && !arg_no_tail && !arg_since && arg_lines == ARG_LINES_DEFAULT)
@@ -1942,7 +1942,6 @@ static int setup_keys(void) {
                 if (hn)
                         hostname_cleanup(hn);
 
-                char tsb[FORMAT_TIMESPAN_MAX];
                 fprintf(stderr,
                         "\nNew keys have been generated for host %s%s" SD_ID128_FORMAT_STR ".\n"
                         "\n"
@@ -1961,7 +1960,7 @@ static int setup_keys(void) {
                         SD_ID128_FORMAT_VAL(machine),
                         ansi_highlight(), ansi_normal(),
                         p,
-                        format_timespan(tsb, sizeof(tsb), arg_interval, 0),
+                        FORMAT_TIMESPAN(arg_interval, 0),
                         ansi_highlight(), ansi_normal(),
                         ansi_highlight_red());
                 fflush(stderr);
@@ -2014,7 +2013,7 @@ static int verify(sd_journal *j) {
                 else if (k < 0)
                         r = log_warning_errno(k, "FAIL: %s (%m)", f->path);
                 else {
-                        char a[FORMAT_TIMESTAMP_MAX], b[FORMAT_TIMESTAMP_MAX], c[FORMAT_TIMESPAN_MAX];
+                        char a[FORMAT_TIMESTAMP_MAX], b[FORMAT_TIMESTAMP_MAX];
                         log_info("PASS: %s", f->path);
 
                         if (arg_verify_key && JOURNAL_HEADER_SEALED(f->header)) {
@@ -2022,10 +2021,10 @@ static int verify(sd_journal *j) {
                                         log_info("=> Validated from %s to %s, final %s entries not sealed.",
                                                  format_timestamp_maybe_utc(a, sizeof(a), first),
                                                  format_timestamp_maybe_utc(b, sizeof(b), validated),
-                                                 format_timespan(c, sizeof(c), last > validated ? last - validated : 0, 0));
+                                                 FORMAT_TIMESPAN(last > validated ? last - validated : 0, 0));
                                 } else if (last > 0)
                                         log_info("=> No sealing yet, %s of entries not sealed.",
-                                                 format_timespan(c, sizeof(c), last - first, 0));
+                                                 FORMAT_TIMESPAN(last - first, 0));
                                 else
                                         log_info("=> No sealing yet, no entries in file.");
                         }
@@ -2230,7 +2229,7 @@ int main(int argc, char *argv[]) {
                 break;
 
         default:
-                assert_not_reached("Unknown action");
+                assert_not_reached();
         }
 
         if (arg_directory)
@@ -2315,7 +2314,7 @@ int main(int argc, char *argv[]) {
         case ACTION_FLUSH:
         case ACTION_SYNC:
         case ACTION_ROTATE:
-                assert_not_reached("Unexpected action.");
+                assert_not_reached();
 
         case ACTION_PRINT_HEADER:
                 journal_print_header(j);
@@ -2328,14 +2327,13 @@ int main(int argc, char *argv[]) {
 
         case ACTION_DISK_USAGE: {
                 uint64_t bytes = 0;
-                char sbytes[FORMAT_BYTES_MAX];
 
                 r = sd_journal_get_usage(j, &bytes);
                 if (r < 0)
                         goto finish;
 
                 printf("Archived and active journals take up %s in the file system.\n",
-                       format_bytes(sbytes, sizeof(sbytes), bytes));
+                       FORMAT_BYTES(bytes));
                 goto finish;
         }
 
@@ -2382,7 +2380,7 @@ int main(int argc, char *argv[]) {
                 break;
 
         default:
-                assert_not_reached("Unknown action");
+                assert_not_reached();
         }
 
         if (arg_boot_offset != 0 &&
index 30f04f5383451e1043a916831cb47ac36ba2e4c4..d410d7cf19ce5ddf9412f30fae073f124f8e5617 100644 (file)
@@ -199,10 +199,6 @@ static int determine_space(Server *s, uint64_t *available, uint64_t *limit) {
 }
 
 void server_space_usage_message(Server *s, JournalStorage *storage) {
-        char fb1[FORMAT_BYTES_MAX], fb2[FORMAT_BYTES_MAX], fb3[FORMAT_BYTES_MAX],
-             fb4[FORMAT_BYTES_MAX], fb5[FORMAT_BYTES_MAX], fb6[FORMAT_BYTES_MAX];
-        JournalMetrics *metrics;
-
         assert(s);
 
         if (!storage)
@@ -211,32 +207,29 @@ void server_space_usage_message(Server *s, JournalStorage *storage) {
         if (cache_space_refresh(s, storage) < 0)
                 return;
 
-        metrics = &storage->metrics;
-        format_bytes(fb1, sizeof(fb1), storage->space.vfs_used);
-        format_bytes(fb2, sizeof(fb2), metrics->max_use);
-        format_bytes(fb3, sizeof(fb3), metrics->keep_free);
-        format_bytes(fb4, sizeof(fb4), storage->space.vfs_available);
-        format_bytes(fb5, sizeof(fb5), storage->space.limit);
-        format_bytes(fb6, sizeof(fb6), storage->space.available);
+        const JournalMetrics *metrics = &storage->metrics;
 
         server_driver_message(s, 0,
                               "MESSAGE_ID=" SD_MESSAGE_JOURNAL_USAGE_STR,
                               LOG_MESSAGE("%s (%s) is %s, max %s, %s free.",
-                                          storage->name, storage->path, fb1, fb5, fb6),
+                                          storage->name, storage->path,
+                                          FORMAT_BYTES(storage->space.vfs_used),
+                                          FORMAT_BYTES(storage->space.limit),
+                                          FORMAT_BYTES(storage->space.available)),
                               "JOURNAL_NAME=%s", storage->name,
                               "JOURNAL_PATH=%s", storage->path,
                               "CURRENT_USE=%"PRIu64, storage->space.vfs_used,
-                              "CURRENT_USE_PRETTY=%s", fb1,
+                              "CURRENT_USE_PRETTY=%s", FORMAT_BYTES(storage->space.vfs_used),
                               "MAX_USE=%"PRIu64, metrics->max_use,
-                              "MAX_USE_PRETTY=%s", fb2,
+                              "MAX_USE_PRETTY=%s", FORMAT_BYTES(metrics->max_use),
                               "DISK_KEEP_FREE=%"PRIu64, metrics->keep_free,
-                              "DISK_KEEP_FREE_PRETTY=%s", fb3,
+                              "DISK_KEEP_FREE_PRETTY=%s", FORMAT_BYTES(metrics->keep_free),
                               "DISK_AVAILABLE=%"PRIu64, storage->space.vfs_available,
-                              "DISK_AVAILABLE_PRETTY=%s", fb4,
+                              "DISK_AVAILABLE_PRETTY=%s", FORMAT_BYTES(storage->space.vfs_available),
                               "LIMIT=%"PRIu64, storage->space.limit,
-                              "LIMIT_PRETTY=%s", fb5,
+                              "LIMIT_PRETTY=%s", FORMAT_BYTES(storage->space.limit),
                               "AVAILABLE=%"PRIu64, storage->space.available,
-                              "AVAILABLE_PRETTY=%s", fb6,
+                              "AVAILABLE_PRETTY=%s", FORMAT_BYTES(storage->space.available),
                               NULL);
 }
 
@@ -1113,7 +1106,6 @@ void server_dispatch_message(
 }
 
 int server_flush_to_var(Server *s, bool require_flag_file) {
-        char ts[FORMAT_TIMESPAN_MAX];
         sd_journal *j = NULL;
         const char *fn;
         unsigned n = 0;
@@ -1206,7 +1198,7 @@ finish:
         server_driver_message(s, 0, NULL,
                               LOG_MESSAGE("Time spent on flushing to %s is %s for %u entries.",
                                           s->system_storage.path,
-                                          format_timespan(ts, sizeof(ts), usec_sub_unsigned(now(CLOCK_MONOTONIC), start), 0),
+                                          FORMAT_TIMESPAN(usec_sub_unsigned(now(CLOCK_MONOTONIC), start), 0),
                                           n),
                               NULL);
 
index c6720b6b13950813d1a46a7011ded4a2d5e4ffba..0a90091a86335c0fce27b6b55eea1093b21e7eba 100644 (file)
@@ -449,7 +449,7 @@ static int stdout_stream_line(StdoutStream *s, char *p, LineBreak line_break) {
                 return stdout_stream_log(s, orig, line_break);
         }
 
-        assert_not_reached("Unknown stream state");
+        assert_not_reached();
 }
 
 static int stdout_stream_found(
index 4117188f147463913050a1a465e815b9316d076a..893832461e46d6d6176ee099a672e5040cb44010 100644 (file)
@@ -15,7 +15,7 @@ if want_kernel_install
 
         if install_sysconfdir
                 meson.add_install_script('sh', '-c',
-                                         mkdir_p.format(join_paths(sysconfdir, 'kernel/install.d')))
+                                         mkdir_p.format(sysconfdir / 'kernel/install.d'))
         endif
 
 endif
index dc8ff19d1a2448811c6df4cffbada36a62448c1a..fb89f7c7f1944386b5e3e0bf76064731a3600861 100644 (file)
@@ -238,7 +238,7 @@ int sd_dhcp_client_set_callback(
 int sd_dhcp_client_set_request_broadcast(sd_dhcp_client *client, int broadcast) {
         assert_return(client, -EINVAL);
 
-        client->request_broadcast = !!broadcast;
+        client->request_broadcast = broadcast;
 
         return 0;
 }
@@ -1308,7 +1308,7 @@ static int client_timeout_resend(
                 goto error;
 
         default:
-                assert_not_reached("Unhandled choice");
+                assert_not_reached();
         }
 
         r = event_reset_time(client->event, &client->timeout_resend,
@@ -1686,7 +1686,6 @@ static int client_handle_ack(sd_dhcp_client *client, DHCPMessage *ack, size_t le
 
 static int client_set_lease_timeouts(sd_dhcp_client *client) {
         usec_t time_now;
-        char time_string[FORMAT_TIMESPAN_MAX];
         int r;
 
         assert(client);
@@ -1748,7 +1747,7 @@ static int client_set_lease_timeouts(sd_dhcp_client *client) {
                 return 0;
 
         log_dhcp_client(client, "lease expires in %s",
-                        format_timespan(time_string, FORMAT_TIMESPAN_MAX, client->expire_time - time_now, USEC_PER_SEC));
+                        FORMAT_TIMESPAN(client->expire_time - time_now, USEC_PER_SEC));
 
         /* arm T2 timeout */
         r = event_reset_time(client->event, &client->timeout_t2,
@@ -1764,7 +1763,7 @@ static int client_set_lease_timeouts(sd_dhcp_client *client) {
                 return 0;
 
         log_dhcp_client(client, "T2 expires in %s",
-                        format_timespan(time_string, FORMAT_TIMESPAN_MAX, client->t2_time - time_now, USEC_PER_SEC));
+                        FORMAT_TIMESPAN(client->t2_time - time_now, USEC_PER_SEC));
 
         /* arm T1 timeout */
         r = event_reset_time(client->event, &client->timeout_t1,
@@ -1777,14 +1776,13 @@ static int client_set_lease_timeouts(sd_dhcp_client *client) {
 
         if (client->t1_time > time_now)
                 log_dhcp_client(client, "T1 expires in %s",
-                                format_timespan(time_string, FORMAT_TIMESPAN_MAX, client->t1_time - time_now, USEC_PER_SEC));
+                                FORMAT_TIMESPAN(client->t1_time - time_now, USEC_PER_SEC));
 
         return 0;
 }
 
 static int client_handle_message(sd_dhcp_client *client, DHCPMessage *message, int len) {
         DHCP_CLIENT_DONT_DESTROY(client);
-        char time_string[FORMAT_TIMESPAN_MAX];
         int r, notify_event;
 
         assert(client);
@@ -1830,8 +1828,7 @@ static int client_handle_message(sd_dhcp_client *client, DHCPMessage *message, i
                         if (r < 0)
                                 goto error;
 
-                        log_dhcp_client(client, "REBOOT in %s", format_timespan(time_string, FORMAT_TIMESPAN_MAX,
-                                                                                client->start_delay, USEC_PER_SEC));
+                        log_dhcp_client(client, "REBOOT in %s", FORMAT_TIMESPAN(client->start_delay, USEC_PER_SEC));
 
                         client->start_delay = CLAMP(client->start_delay * 2,
                                                     RESTART_AFTER_NAK_MIN_USEC, RESTART_AFTER_NAK_MAX_USEC);
@@ -1899,7 +1896,7 @@ static int client_handle_message(sd_dhcp_client *client, DHCPMessage *message, i
                 r = -EINVAL;
                 goto error;
         default:
-                assert_not_reached("invalid state");
+                assert_not_reached();
         }
 
 error:
index e8c47f429a57d9919a35d49ede69854d7452a9a0..079f154acd3715d861d3dc0a56914dd387c1ca42 100644 (file)
@@ -946,7 +946,6 @@ static int client_timeout_resend(sd_event_source *s, uint64_t usec, void *userda
         usec_t time_now, init_retransmit_time = 0, max_retransmit_time = 0;
         usec_t max_retransmit_duration = 0;
         uint8_t max_retransmit_count = 0;
-        char time_string[FORMAT_TIMESPAN_MAX];
 
         assert(s);
         assert(client);
@@ -1042,7 +1041,7 @@ static int client_timeout_resend(sd_event_source *s, uint64_t usec, void *userda
         }
 
         log_dhcp6_client(client, "Next retransmission in %s",
-                         format_timespan(time_string, FORMAT_TIMESPAN_MAX, client->retransmit_time, USEC_PER_SEC));
+                         FORMAT_TIMESPAN(client->retransmit_time, USEC_PER_SEC));
 
         r = event_reset_time(client->event, &client->timeout_resend,
                              clock_boottime_or_monotonic(),
@@ -1566,7 +1565,6 @@ static int client_get_lifetime(sd_dhcp6_client *client, uint32_t *lifetime_t1,
 static int client_start(sd_dhcp6_client *client, enum DHCP6State state) {
         int r;
         usec_t timeout, time_now;
-        char time_string[FORMAT_TIMESPAN_MAX];
         uint32_t lifetime_t1, lifetime_t2;
 
         assert_return(client, -EINVAL);
@@ -1639,8 +1637,7 @@ static int client_start(sd_dhcp6_client *client, enum DHCP6State state) {
 
                 timeout = client_timeout_compute_random(lifetime_t1 * USEC_PER_SEC);
 
-                log_dhcp6_client(client, "T1 expires in %s",
-                                 format_timespan(time_string, FORMAT_TIMESPAN_MAX, timeout, USEC_PER_SEC));
+                log_dhcp6_client(client, "T1 expires in %s", FORMAT_TIMESPAN(timeout, USEC_PER_SEC));
 
                 r = event_reset_time(client->event, &client->timeout_t1,
                                      clock_boottime_or_monotonic(),
@@ -1652,8 +1649,7 @@ static int client_start(sd_dhcp6_client *client, enum DHCP6State state) {
 
                 timeout = client_timeout_compute_random(lifetime_t2 * USEC_PER_SEC);
 
-                log_dhcp6_client(client, "T2 expires in %s",
-                                 format_timespan(time_string, FORMAT_TIMESPAN_MAX, timeout, USEC_PER_SEC));
+                log_dhcp6_client(client, "T2 expires in %s", FORMAT_TIMESPAN(timeout, USEC_PER_SEC));
 
                 r = event_reset_time(client->event, &client->timeout_t2,
                                      clock_boottime_or_monotonic(),
index 9a77a333175a9be0458fdbb85fce88d6efdf7a6f..6a39f44e6c8634b239740e612328028ca629c0d9 100644 (file)
@@ -225,10 +225,8 @@ static int ipv4acd_on_timeout(sd_event_source *s, uint64_t usec, void *userdata)
                 ipv4acd_set_state(acd, IPV4ACD_STATE_WAITING_PROBE, true);
 
                 if (acd->n_conflict >= MAX_CONFLICTS) {
-                        char ts[FORMAT_TIMESPAN_MAX];
-
                         log_ipv4acd(acd, "Max conflicts reached, delaying by %s",
-                                    format_timespan(ts, sizeof(ts), RATE_LIMIT_INTERVAL_USEC, 0));
+                                    FORMAT_TIMESPAN(RATE_LIMIT_INTERVAL_USEC, 0));
                         r = ipv4acd_set_next_wakeup(acd, RATE_LIMIT_INTERVAL_USEC, PROBE_WAIT_USEC);
                 } else
                         r = ipv4acd_set_next_wakeup(acd, 0, PROBE_WAIT_USEC);
@@ -295,7 +293,7 @@ static int ipv4acd_on_timeout(sd_event_source *s, uint64_t usec, void *userdata)
                 break;
 
         default:
-                assert_not_reached("Invalid state.");
+                assert_not_reached();
         }
 
         return 0;
@@ -411,7 +409,7 @@ static int ipv4acd_on_packet(
                 break;
 
         default:
-                assert_not_reached("Invalid state.");
+                assert_not_reached();
         }
 
         return 0;
index 7b9d63ca3c5b74b98d5969ae27ac4d3ee67b7709..f2cc22db266b1329bbfc6f29503f3fe9980da021 100644 (file)
@@ -360,7 +360,7 @@ void ipv4ll_on_acd(sd_ipv4acd *acd, int event, void *userdata) {
                 break;
 
         default:
-                assert_not_reached("Invalid IPv4ACD event.");
+                assert_not_reached();
         }
 
         return;
index 4d5f1b54cd4d5f01a50604a3d3cba9c5ffd446fa..9fff9929f710c52bf25e2652ab8a6da2027a8b6c 100644 (file)
@@ -279,7 +279,6 @@ static usec_t ndisc_timeout_compute_random(usec_t val) {
 }
 
 static int ndisc_timeout(sd_event_source *s, uint64_t usec, void *userdata) {
-        char time_string[FORMAT_TIMESPAN_MAX];
         sd_ndisc *nd = userdata;
         usec_t time_now;
         int r;
@@ -314,8 +313,7 @@ static int ndisc_timeout(sd_event_source *s, uint64_t usec, void *userdata) {
         }
 
         log_ndisc(nd, "Sent Router Solicitation, next solicitation in %s",
-                  format_timespan(time_string, FORMAT_TIMESPAN_MAX,
-                                  nd->retransmit_time, USEC_PER_SEC));
+                  FORMAT_TIMESPAN(nd->retransmit_time, USEC_PER_SEC));
 
         return 0;
 
index 857401bf6e06df3245ad54769c5153681782250e..79acfa3add5d24a43ee797fa1e676def48999c59 100644 (file)
@@ -301,7 +301,6 @@ static int radv_timeout(sd_event_source *s, uint64_t usec, void *userdata) {
         usec_t min_timeout = SD_RADV_DEFAULT_MIN_TIMEOUT_USEC;
         usec_t max_timeout = SD_RADV_DEFAULT_MAX_TIMEOUT_USEC;
         usec_t time_now, timeout;
-        char time_string[FORMAT_TIMESPAN_MAX];
 
         assert(s);
         assert(ra);
@@ -329,10 +328,7 @@ static int radv_timeout(sd_event_source *s, uint64_t usec, void *userdata) {
         }
 
         timeout = radv_compute_timeout(min_timeout, max_timeout);
-
-        log_radv(ra, "Next Router Advertisement in %s",
-                 format_timespan(time_string, FORMAT_TIMESPAN_MAX,
-                                 timeout, USEC_PER_SEC));
+        log_radv(ra, "Next Router Advertisement in %s", FORMAT_TIMESPAN(timeout, USEC_PER_SEC));
 
         r = event_reset_time(ra->event, &ra->timeout_event_source,
                              clock_boottime_or_monotonic(),
@@ -545,8 +541,6 @@ _public_ int sd_radv_add_prefix(sd_radv *ra, sd_radv_prefix *p, int dynamic) {
         sd_radv_prefix *cur;
         int r;
         _cleanup_free_ char *addr_p = NULL;
-        char time_string_preferred[FORMAT_TIMESPAN_MAX];
-        char time_string_valid[FORMAT_TIMESPAN_MAX];
         usec_t time_now, valid, preferred, valid_until, preferred_until;
 
         assert_return(ra, -EINVAL);
@@ -628,10 +622,8 @@ _public_ int sd_radv_add_prefix(sd_radv *ra, sd_radv_prefix *p, int dynamic) {
 
         log_radv(ra, "Updated prefix %s preferred %s valid %s",
                  strna(addr_p),
-                 format_timespan(time_string_preferred, FORMAT_TIMESPAN_MAX,
-                                 preferred, USEC_PER_SEC),
-                 format_timespan(time_string_valid, FORMAT_TIMESPAN_MAX,
-                                 valid, USEC_PER_SEC));
+                 FORMAT_TIMESPAN(preferred, USEC_PER_SEC),
+                 FORMAT_TIMESPAN(valid, USEC_PER_SEC));
 
         return 0;
 }
@@ -662,7 +654,6 @@ _public_ sd_radv_prefix *sd_radv_remove_prefix(sd_radv *ra,
 }
 
 _public_ int sd_radv_add_route_prefix(sd_radv *ra, sd_radv_route_prefix *p, int dynamic) {
-        char time_string_valid[FORMAT_TIMESPAN_MAX];
         usec_t time_now, valid, valid_until;
         _cleanup_free_ char *pretty = NULL;
         sd_radv_route_prefix *cur;
@@ -732,7 +723,7 @@ _public_ int sd_radv_add_route_prefix(sd_radv *ra, sd_radv_route_prefix *p, int
 
         log_radv(ra, "Updated route prefix %s valid %s",
                  strna(pretty),
-                 format_timespan(time_string_valid, FORMAT_TIMESPAN_MAX, valid, USEC_PER_SEC));
+                 FORMAT_TIMESPAN(valid, USEC_PER_SEC));
 
         return 0;
 }
index f4aab85ed40b47d87044a92801a5ed7be1b90bd0..e369f5a5921c89c206e5b25e935e6667cc360901 100644 (file)
@@ -30,7 +30,7 @@ static void acd_handler(sd_ipv4acd *acd, int event, void *userdata) {
                 log_error("the client was stopped");
                 break;
         default:
-                assert_not_reached("invalid ACD event");
+                assert_not_reached();
         }
 }
 
index 6e0fdcd769ae5e483e9b0bfe78ce3e4df3c0144f..10db7f6c4bcde2d24c0b2c57553ee6b1145020c0 100644 (file)
@@ -34,7 +34,7 @@ static be32_t xid;
 static sd_event_source *test_hangcheck;
 
 static int test_dhcp_hangcheck(sd_event_source *s, uint64_t usec, void *userdata) {
-        assert_not_reached("Test case should have completed in 2 seconds");
+        assert_not_reached();
 
         return 0;
 }
index a72c13684dea6512061fe81efbb5863502f9644f..5511350489deed5a5115ac8d90d0e7f4be010086 100644 (file)
@@ -560,10 +560,8 @@ static int test_advertise_option(sd_event *e) {
         return 0;
 }
 
-static int test_hangcheck(sd_event_source *s, uint64_t usec, void *userdata) {
-        assert_not_reached("Test case should have completed in 2 seconds");
-
-        return 0;
+static int test_check_completed_in_2_seconds(sd_event_source *s, uint64_t usec, void *userdata) {
+        assert_not_reached();
 }
 
 static void test_client_solicit_cb(sd_dhcp6_client *client, int event,
@@ -861,14 +859,8 @@ static int test_client_verify_information_request(DHCP6Message *information_requ
                         break;
 
                 case SD_DHCP6_OPTION_IA_NA:
-                        assert_not_reached("IA TA option must not be present");
-
-                        break;
-
                 case SD_DHCP6_OPTION_SERVERID:
-                        assert_not_reached("Server ID option must not be present");
-
-                        break;
+                        assert_not_reached();
 
                 case SD_DHCP6_OPTION_ELAPSED_TIME:
                         assert_se(!found_elapsed_time);
@@ -965,7 +957,7 @@ static int test_client_solicit(sd_event *e) {
 
         assert_se(sd_event_add_time_relative(e, &hangcheck, clock_boottime_or_monotonic(),
                                              2 * USEC_PER_SEC, 0,
-                                             test_hangcheck, NULL) >= 0);
+                                             test_check_completed_in_2_seconds, NULL) >= 0);
 
         assert_se(sd_dhcp6_client_set_local_address(client, &address) >= 0);
 
index a253acbd8355409b762e62404de2371669a9bb43..3fea894f302f26edd68e8f474991528ffa6acddc 100644 (file)
@@ -38,7 +38,7 @@ static void ll_handler(sd_ipv4ll *ll, int event, void *userdata) {
                 log_error("the client was stopped with address %s", strna(address));
                 break;
         default:
-                assert_not_reached("invalid LL event");
+                assert_not_reached();
         }
 }
 
index ce596bb96ab6d229f391577c590e9421fe0a8f05..5e50453c35fafa62ee78de495e60040b5b6b133c 100644 (file)
@@ -31,7 +31,6 @@ static send_ra_t send_ra_function;
 
 static void router_dump(sd_ndisc_router *rt) {
         struct in6_addr addr;
-        char buf[FORMAT_TIMESTAMP_MAX];
         uint8_t hop_limit;
         uint64_t t, flags;
         uint32_t mtu;
@@ -45,7 +44,7 @@ static void router_dump(sd_ndisc_router *rt) {
         assert_se(sd_ndisc_router_get_address(rt, &addr) == -ENODATA);
 
         assert_se(sd_ndisc_router_get_timestamp(rt, CLOCK_REALTIME, &t) >= 0);
-        log_info("Timestamp: %s", format_timestamp(buf, sizeof(buf), t));
+        log_info("Timestamp: %s", FORMAT_TIMESTAMP(t));
 
         assert_se(sd_ndisc_router_get_timestamp(rt, CLOCK_MONOTONIC, &t) >= 0);
         log_info("Monotonic: %" PRIu64, t);
@@ -318,9 +317,6 @@ static int test_timeout_value(uint8_t flags) {
         static usec_t last = 0;
         sd_ndisc *nd = test_timeout_nd;
         usec_t min, max;
-        char time_string_min[FORMAT_TIMESPAN_MAX];
-        char time_string_nd[FORMAT_TIMESPAN_MAX];
-        char time_string_max[FORMAT_TIMESPAN_MAX];
 
         assert_se(nd);
         assert_se(nd->event);
@@ -348,17 +344,12 @@ static int test_timeout_value(uint8_t flags) {
                         NDISC_MAX_ROUTER_SOLICITATION_INTERVAL / 10;
         }
 
-        format_timespan(time_string_min, FORMAT_TIMESPAN_MAX,
-                        min, USEC_PER_MSEC);
-        format_timespan(time_string_nd, FORMAT_TIMESPAN_MAX,
-                        nd->retransmit_time, USEC_PER_MSEC);
-        format_timespan(time_string_max, FORMAT_TIMESPAN_MAX,
-                        max, USEC_PER_MSEC);
-
         log_info("backoff timeout interval %2d %s%s <= %s <= %s",
                  count,
-                 (last * 2 > NDISC_MAX_ROUTER_SOLICITATION_INTERVAL)? "(max) ": "",
-                 time_string_min, time_string_nd, time_string_max);
+                 last * 2 > NDISC_MAX_ROUTER_SOLICITATION_INTERVAL ? "(max) ": "",
+                 FORMAT_TIMESPAN(min, USEC_PER_MSEC),
+                 FORMAT_TIMESPAN(nd->retransmit_time, USEC_PER_MSEC),
+                 FORMAT_TIMESPAN(max, USEC_PER_MSEC));
 
         assert_se(min <= nd->retransmit_time);
         assert_se(max >= nd->retransmit_time);
index 154d9acd2a295f3043819980ffd8d68cd25ce3dc..479b81b352045e4ad3cac9d48317bd634f499ae7 100644 (file)
@@ -171,7 +171,7 @@ libsystemd_static = static_library(
         c_args : libsystemd_c_args)
 
 libsystemd_sym = files('libsystemd.sym')
-libsystemd_sym_path = join_paths(meson.current_source_dir(), 'libsystemd.sym')
+libsystemd_sym_path = meson.current_source_dir() / 'libsystemd.sym'
 
 static_libsystemd = get_option('static-libsystemd')
 static_libsystemd_pic = static_libsystemd == 'true' or static_libsystemd == 'pic'
index b11ebb3f65f146b6a4929628db2c02c18e53a9d5..1159af46cdf25ebb98764e7634d6b4bd7cfdecfd 100644 (file)
@@ -37,11 +37,11 @@ int bus_container_connect_socket(sd_bus *b) {
 
         r = namespace_open(b->nspid, &pidnsfd, &mntnsfd, NULL, &usernsfd, &rootfd);
         if (r < 0)
-                return r;
+                return log_debug_errno(r, "Failed to open namespace of PID "PID_FMT": %m", b->nspid);
 
         b->input_fd = socket(b->sockaddr.sa.sa_family, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
         if (b->input_fd < 0)
-                return -errno;
+                return log_debug_errno(errno, "Failed to create a socket: %m");
 
         b->input_fd = fd_move_above_stdio(b->input_fd);
 
@@ -50,12 +50,12 @@ int bus_container_connect_socket(sd_bus *b) {
         bus_socket_setup(b);
 
         if (socketpair(AF_UNIX, SOCK_SEQPACKET|SOCK_CLOEXEC, 0, pair) < 0)
-                return -errno;
+                return log_debug_errno(errno, "Failed to create a socket pair: %m");
 
         r = namespace_fork("(sd-buscntrns)", "(sd-buscntr)", NULL, 0, FORK_RESET_SIGNALS|FORK_DEATHSIG,
                            pidnsfd, mntnsfd, -1, usernsfd, rootfd, &child);
         if (r < 0)
-                return r;
+                return log_debug_errno(r, "Failed to create namespace for (sd-buscntr): %m");
         if (r == 0) {
                 pair[0] = safe_close(pair[0]);
 
@@ -80,20 +80,22 @@ int bus_container_connect_socket(sd_bus *b) {
 
         n = read(pair[0], &error_buf, sizeof(error_buf));
         if (n < 0)
-                return -errno;
+                return log_debug_errno(errno, "Failed to read error status from (sd-buscntr): %m");
 
         if (n > 0) {
                 if (n != sizeof(error_buf))
-                        return -EIO;
+                        return log_debug_errno(SYNTHETIC_ERRNO(EIO),
+                                               "Read error status of unexpected length %zd from (sd-buscntr): %m", n);
 
                 if (error_buf < 0)
-                        return -EIO;
+                        return log_debug_errno(SYNTHETIC_ERRNO(EBADMSG),
+                                               "Got unexpected error status from (sd-buscntr): %m");
 
                 if (error_buf == EINPROGRESS)
                         return 1;
 
                 if (error_buf > 0)
-                        return -error_buf;
+                        return log_debug_errno(error_buf, "Got error from (sd-buscntr): %m");
         }
 
         return bus_socket_start_auth(b);
index d5d22b0d8c64f086cd97dd28ecc7dfcde02e1103..d50cd1eedd1c2ee48a0ca72035ffe0da0c30c0db 100644 (file)
@@ -55,15 +55,11 @@ _public_ int sd_bus_message_dump(sd_bus_message *m, FILE *f, uint64_t flags) {
                 f = stdout;
 
         if (flags & SD_BUS_MESSAGE_DUMP_WITH_HEADER) {
-                char buf[FORMAT_TIMESTAMP_MAX];
-                const char *p;
                 usec_t ts = m->realtime;
 
                 if (ts == 0)
                         ts = now(CLOCK_REALTIME);
 
-                p = format_timestamp_style(buf, sizeof(buf), ts, TIMESTAMP_US_UTC);
-
                 fprintf(f,
                         "%s%s%s Type=%s%s%s  Endian=%c  Flags=%u  Version=%u",
                         m->header->type == SD_BUS_MESSAGE_METHOD_ERROR ? ansi_highlight_red() :
@@ -90,9 +86,7 @@ _public_ int sd_bus_message_dump(sd_bus_message *m, FILE *f, uint64_t flags) {
                 if (m->reply_cookie != 0)
                         fprintf(f, "  ReplyCookie=%" PRIu64, m->reply_cookie);
 
-                fprintf(f, "  Timestamp=\"%s\"", strna(p));
-
-                fputs("\n", f);
+                fprintf(f, "  Timestamp=\"%s\"\n", strna(FORMAT_TIMESTAMP_STYLE(ts, TIMESTAMP_US_UTC)));
 
                 if (m->sender)
                         fprintf(f, "  Sender=%s%s%s", ansi_highlight(), m->sender, ansi_normal());
@@ -265,7 +259,7 @@ _public_ int sd_bus_message_dump(sd_bus_message *m, FILE *f, uint64_t flags) {
                         break;
 
                 default:
-                        assert_not_reached("Unknown basic type.");
+                        assert_not_reached();
                 }
         }
 
@@ -395,10 +389,8 @@ int bus_creds_dump(sd_bus_creds *c, FILE *f, bool terse) {
                 fprintf(f, "%sFSGID=%s"GID_FMT"%s", prefix, color, c->fsgid, suffix);
 
         if (c->mask & SD_BUS_CREDS_SUPPLEMENTARY_GIDS) {
-                unsigned i;
-
                 fprintf(f, "%sSupplementaryGIDs=%s", prefix, color);
-                for (i = 0; i < c->n_supplementary_gids; i++)
+                for (unsigned i = 0; i < c->n_supplementary_gids; i++)
                         fprintf(f, "%s" GID_FMT, i > 0 ? " " : "", c->supplementary_gids[i]);
                 fprintf(f, "%s", suffix);
         }
index 7483b46a11d7dc79367c0351573c3ed577e0ef10..bdfa145ab7d640bc69c65737cd793ee258dcf2da 100644 (file)
@@ -252,10 +252,15 @@ int bus_error_setfv(sd_bus_error *e, const char *name, const char *format, va_li
                         return -ENOMEM;
                 }
 
-                /* If we hit OOM on formatting the pretty message, we ignore
-                 * this, since we at least managed to write the error name */
-                if (format)
-                        (void) vasprintf((char**) &e->message, format, ap);
+                if (format) {
+                        _cleanup_free_ char *mesg = NULL;
+
+                        /* If we hit OOM on formatting the pretty message, we ignore
+                         * this, since we at least managed to write the error name */
+
+                        if (vasprintf(&mesg, format, ap) >= 0)
+                                e->message = TAKE_PTR(mesg);
+                }
 
                 e->_need_free = 1;
         }
index 850540a7852923f598a5d77e02859ae89971187b..07decfd1f3d7463739eaa1123589f7bf6783988c 100644 (file)
@@ -87,7 +87,7 @@ int bus_gvariant_get_size(const char *signature) {
                         return -EINVAL;
 
                 default:
-                        assert_not_reached("Unknown signature type");
+                        assert_not_reached();
                 }
 
                 p += n;
@@ -164,7 +164,7 @@ int bus_gvariant_get_alignment(const char *signature) {
                 }
 
                 default:
-                        assert_not_reached("Unknown signature type");
+                        assert_not_reached();
                 }
 
                 if (a < 0)
@@ -229,7 +229,7 @@ int bus_gvariant_is_fixed_size(const char *signature) {
                 }
 
                 default:
-                        assert_not_reached("Unknown signature type");
+                        assert_not_reached();
                 }
 
                 p += n;
@@ -270,7 +270,7 @@ size_t bus_gvariant_read_word_le(void *p, size_t sz) {
         else if (sz == 8)
                 return le64toh(x.u64);
 
-        assert_not_reached("unknown word width");
+        assert_not_reached();
 }
 
 void bus_gvariant_write_word_le(void *p, size_t sz, size_t value) {
@@ -293,7 +293,7 @@ void bus_gvariant_write_word_le(void *p, size_t sz, size_t value) {
         else if (sz == 8)
                 x.u64 = htole64((uint64_t) value);
         else
-                assert_not_reached("unknown word width");
+                assert_not_reached();
 
         memcpy(p, &x, sz);
 }
index 648f1ca62fe3b2d1ebae75743f4432d74a4cfea5..ff8cf4ee0e4264b2a6532a2d899dce1157055560 100644 (file)
@@ -199,7 +199,7 @@ static bool value_node_test(
                 return false;
 
         default:
-                assert_not_reached("Invalid node type");
+                assert_not_reached();
         }
 }
 
@@ -234,7 +234,7 @@ static bool value_node_same(
                 return streq(node->value.str, value_str);
 
         default:
-                assert_not_reached("Invalid node type");
+                assert_not_reached();
         }
 }
 
@@ -375,7 +375,7 @@ int bus_match_run(
                 break;
 
         default:
-                assert_not_reached("Unknown match type.");
+                assert_not_reached();
         }
 
         if (BUS_MATCH_CAN_HASH(node->type)) {
index 20f7396c74ef1ebf80734e2014c823cdf52036a7..954b159bf2e40a0eaacbcf9b348fb1933bc92d4b 100644 (file)
@@ -2275,7 +2275,7 @@ _public_ int sd_bus_message_close_container(sd_bus_message *m) {
         else if (IN_SET(c->enclosing, SD_BUS_TYPE_STRUCT, SD_BUS_TYPE_DICT_ENTRY))
                 r = bus_message_close_struct(m, c, true);
         else
-                assert_not_reached("Unknown container type");
+                assert_not_reached();
 
         free(c->signature);
         free(c->offsets);
@@ -3247,7 +3247,7 @@ static int container_next_item(sd_bus_message *m, struct bus_container *c, size_
         } else if (c->enclosing == SD_BUS_TYPE_VARIANT)
                 goto end;
         else
-                assert_not_reached("Unknown container type");
+                assert_not_reached();
 
         return 0;
 
@@ -3460,7 +3460,7 @@ _public_ int sd_bus_message_read_basic(sd_bus_message *m, char type, void *p) {
                         }
 
                         default:
-                                assert_not_reached("unexpected type");
+                                assert_not_reached();
                         }
                 }
 
@@ -3575,7 +3575,7 @@ _public_ int sd_bus_message_read_basic(sd_bus_message *m, char type, void *p) {
                         }
 
                         default:
-                                assert_not_reached("Unknown basic type...");
+                                assert_not_reached();
                         }
                 }
         }
index a0009a7a87d7ccdbabfded3f96da9054549007a1..9f289575ef25809ca39e65462ff2c15f75c6f8de 100644 (file)
@@ -161,7 +161,7 @@ void bus_slot_disconnect(sd_bus_slot *slot, bool unref) {
                 break;
 
         default:
-                assert_not_reached("Wut? Unknown slot type?");
+                assert_not_reached();
         }
 
         bus = slot->bus;
index 378774fe8b54f1287ef2fde5b9401f0eeab9ac5e..b408d657a5e7f031755e3cfe6f85ffb31edb37e2 100644 (file)
@@ -12,6 +12,7 @@
 #include "bus-internal.h"
 #include "bus-message.h"
 #include "bus-socket.h"
+#include "escape.h"
 #include "fd-util.h"
 #include "format-util.h"
 #include "fs-util.h"
@@ -962,8 +963,17 @@ int bus_socket_exec(sd_bus *b) {
         assert(b->exec_path);
         assert(b->busexec_pid == 0);
 
-        log_debug("sd-bus: starting bus%s%s with %s...",
-                  b->description ? " " : "", strempty(b->description), b->exec_path);
+        if (DEBUG_LOGGING) {
+                _cleanup_free_ char *line = NULL;
+
+                if (b->exec_argv)
+                        line = quote_command_line(b->exec_argv);
+
+                log_debug("sd-bus: starting bus%s%s with %s%s",
+                          b->description ? " " : "", strempty(b->description),
+                          line ?: b->exec_path,
+                          b->exec_argv && !line ? "…" : "");
+        }
 
         r = socketpair(AF_UNIX, SOCK_STREAM|SOCK_NONBLOCK|SOCK_CLOEXEC, 0, s);
         if (r < 0)
@@ -984,10 +994,8 @@ int bus_socket_exec(sd_bus *b) {
 
                 if (b->exec_argv)
                         execvp(b->exec_path, b->exec_argv);
-                else {
-                        const char *argv[] = { b->exec_path, NULL };
-                        execvp(b->exec_path, (char**) argv);
-                }
+                else
+                        execvp(b->exec_path, STRV_MAKE(b->exec_path));
 
                 _exit(EXIT_FAILURE);
         }
index a32e2f5e208524f197c7ed2fd98ec784ed6c888a..0e5c8cf477d2f0db1c84bd7e9061e68f849c756e 100644 (file)
@@ -39,6 +39,7 @@
 #include "parse-util.h"
 #include "path-util.h"
 #include "process-util.h"
+#include "stdio-util.h"
 #include "string-util.h"
 #include "strv.h"
 #include "user-util.h"
@@ -1617,7 +1618,7 @@ static int user_and_machine_valid(const char *user_and_machine) {
                 if (!user)
                         return -ENOMEM;
 
-                if (!isempty(user) && !valid_user_group_name(user, VALID_USER_RELAX))
+                if (!isempty(user) && !valid_user_group_name(user, VALID_USER_RELAX | VALID_USER_ALLOW_NUMERIC))
                         return false;
 
                 h++;
@@ -1648,17 +1649,25 @@ static int user_and_machine_equivalent(const char *user_and_machine) {
 
         /* Otherwise, if we are root, then we can also allow the ".host" syntax, as that's the user this
          * would connect to. */
-        if (geteuid() == 0 && STR_IN_SET(user_and_machine, ".host", "root@.host"))
+        uid_t uid = geteuid();
+
+        if (uid == 0 && STR_IN_SET(user_and_machine, ".host", "root@.host", "0@.host"))
                 return true;
 
-        /* Otherwise, we have to figure our user name, and compare things with that. */
-        un = getusername_malloc();
-        if (!un)
-                return -ENOMEM;
+        /* Otherwise, we have to figure out our user id and name, and compare things with that. */
+        char buf[DECIMAL_STR_MAX(uid_t)];
+        xsprintf(buf, UID_FMT, uid);
+
+        f = startswith(user_and_machine, buf);
+        if (!f) {
+                un = getusername_malloc();
+                if (!un)
+                        return -ENOMEM;
 
-        f = startswith(user_and_machine, un);
-        if (!f)
-                return false;
+                f = startswith(user_and_machine, un);
+                if (!f)
+                        return false;
+        }
 
         return STR_IN_SET(f, "@", "@.host");
 }
@@ -2536,7 +2545,7 @@ _public_ int sd_bus_get_events(sd_bus *bus) {
                 break;
 
         default:
-                assert_not_reached("Unknown state");
+                assert_not_reached();
         }
 
         return flags;
@@ -2595,7 +2604,7 @@ _public_ int sd_bus_get_timeout(sd_bus *bus, uint64_t *timeout_usec) {
                 return 0;
 
         default:
-                assert_not_reached("Unknown or unexpected stat");
+                assert_not_reached();
         }
 }
 
@@ -3054,7 +3063,7 @@ static int bus_exit_now(sd_bus *bus) {
         else
                 exit(EXIT_FAILURE);
 
-        assert_not_reached("exit() didn't exit?");
+        assert_not_reached();
 }
 
 static int process_closing_reply_callback(sd_bus *bus, struct reply_callback *c) {
@@ -3225,7 +3234,7 @@ static int bus_process_internal(sd_bus *bus, sd_bus_message **ret) {
                 return process_closing(bus, ret);
 
         default:
-                assert_not_reached("Unknown state");
+                assert_not_reached();
         }
 
         if (ERRNO_IS_DISCONNECT(r)) {
index 13c08fe2955c21f3666c07051155497d6135e25d..317653bedc27cd5b78d0564dd94d5aba8151c44a 100644 (file)
@@ -57,7 +57,7 @@ static void server(sd_bus *b, size_t *result) {
                         return;
 
                 } else if (!sd_bus_message_is_signal(m, NULL, NULL))
-                        assert_not_reached("Unknown method");
+                        assert_not_reached();
         }
 }
 
index ea7efe68e49a03cab33dd2f131f1dc653a748614..ba94804869ce71a22951806ec17b1dd17a8516bf 100644 (file)
@@ -121,7 +121,7 @@ int main(int argc, char *argv[]) {
 
         OBJECT_PATH_FOREACH_PREFIX(prefix, "/") {
                 log_info("<%s>", prefix);
-                assert_not_reached("???");
+                assert_not_reached();
         }
 
         r = 0;
index 388128bf330857332dfe81b720ee84cd449c6beb..02049db667a4e866cb280302469c7ceb7f5d6f35 100644 (file)
@@ -639,7 +639,7 @@ int device_read_uevent_file(sd_device *device) {
 
                         break;
                 default:
-                        assert_not_reached("Invalid state when parsing uevent file");
+                        assert_not_reached();
                 }
 
         if (major) {
index e9199deb418c8b26ddd1ee790c5c0700def65e2d..cb8f54b1d522b03c83fdb2f3e9875f94ba0d0e65 100644 (file)
@@ -915,7 +915,7 @@ static void source_disconnect(sd_event_source *s) {
         }
 
         default:
-                assert_not_reached("Wut? I shouldn't exist.");
+                assert_not_reached();
         }
 
         if (s->pending)
@@ -2407,7 +2407,7 @@ static int event_source_offline(
                 break;
 
         default:
-                assert_not_reached("Wut? I shouldn't exist.");
+                assert_not_reached();
         }
 
         /* Always reshuffle time prioq, as the ratelimited flag may be changed. */
@@ -2495,7 +2495,7 @@ static int event_source_online(
                 break;
 
         default:
-                assert_not_reached("Wut? I shouldn't exist.");
+                assert_not_reached();
         }
 
         s->enabled = enabled;
@@ -3569,7 +3569,7 @@ static int source_dispatch(sd_event_source *s) {
         case SOURCE_WATCHDOG:
         case _SOURCE_EVENT_SOURCE_TYPE_MAX:
         case _SOURCE_EVENT_SOURCE_TYPE_INVALID:
-                assert_not_reached("Wut? I shouldn't exist.");
+                assert_not_reached();
         }
 
         s->dispatching = false;
@@ -3929,7 +3929,7 @@ static int process_epoll(sd_event *e, usec_t timeout, int64_t threshold, int64_t
                                         break;
 
                                 default:
-                                        assert_not_reached("Unexpected event source type");
+                                        assert_not_reached();
                                 }
 
                                 break;
@@ -3953,7 +3953,7 @@ static int process_epoll(sd_event *e, usec_t timeout, int64_t threshold, int64_t
                                 break;
 
                         default:
-                                assert_not_reached("Invalid wake-up pointer");
+                                assert_not_reached();
                         }
                 }
                 if (r < 0)
index 7ff1452e0845c70886ef763d3ac93717ab8ccd16..e28885b5e06c6931ef899b73f1e2dd9da380fc9a 100644 (file)
@@ -5,6 +5,7 @@
 #include "sd-event.h"
 
 #include "alloc-util.h"
+#include "exec-util.h"
 #include "fd-util.h"
 #include "fs-util.h"
 #include "log.h"
@@ -54,7 +55,7 @@ static int io_handler(sd_event_source *s, int fd, uint32_t revents, void *userda
                 else
                         assert_se(sd_event_source_set_enabled(s, SD_EVENT_OFF) >= 0);
         } else
-                assert_not_reached("Yuck!");
+                assert_not_reached();
 
         return 1;
 }
@@ -169,7 +170,7 @@ static int time_handler(sd_event_source *s, uint64_t usec, void *userdata) {
                         got_c = true;
                 }
         } else
-                assert_not_reached("Huh?");
+                assert_not_reached();
 
         return 2;
 }
@@ -451,7 +452,7 @@ static int inotify_handler(sd_event_source *s, const struct inotify_event *ev, v
                 log_info("inotify-handler <%s>: delete of %s", description, ev->name);
                 assert_se(streq(ev->name, "sub"));
         } else
-                assert_not_reached("unexpected inotify event");
+                assert_not_reached();
 
         maybe_exit(s, c);
         return 1;
@@ -469,7 +470,7 @@ static int delete_self_handler(sd_event_source *s, const struct inotify_event *e
         } else if (ev->mask & IN_IGNORED) {
                 log_info("delete-self-handler: ignore");
         } else
-                assert_not_reached("unexpected inotify event (delete-self)");
+                assert_not_reached();
 
         maybe_exit(s, c);
         return 1;
index 2c17435de2d621cc506c7d77f83857d1cdab2fc7..abbe35c33b0b94375bede6013006fbef918f2ec4 100644 (file)
@@ -3269,20 +3269,12 @@ fail:
         log_error("File corrupt");
 }
 
-static const char* format_timestamp_safe(char *buf, size_t l, usec_t t) {
-        const char *x;
-
-        x = format_timestamp(buf, l, t);
-        if (x)
-                return x;
-        return " --- ";
-}
+/* Note: the lifetime of the compound literal is the immediately surrounding block. */
+#define FORMAT_TIMESTAMP_SAFE(t) (FORMAT_TIMESTAMP(t) ?: " --- ")
 
 void journal_file_print_header(JournalFile *f) {
         char a[SD_ID128_STRING_MAX], b[SD_ID128_STRING_MAX], c[SD_ID128_STRING_MAX], d[SD_ID128_STRING_MAX];
-        char x[FORMAT_TIMESTAMP_MAX], y[FORMAT_TIMESTAMP_MAX], z[FORMAT_TIMESTAMP_MAX];
         struct stat st;
-        char bytes[FORMAT_BYTES_MAX];
 
         assert(f);
         assert(f->header);
@@ -3329,9 +3321,9 @@ void journal_file_print_header(JournalFile *f) {
                yes_no(journal_file_rotate_suggested(f, 0)),
                le64toh(f->header->head_entry_seqnum), le64toh(f->header->head_entry_seqnum),
                le64toh(f->header->tail_entry_seqnum), le64toh(f->header->tail_entry_seqnum),
-               format_timestamp_safe(x, sizeof(x), le64toh(f->header->head_entry_realtime)), le64toh(f->header->head_entry_realtime),
-               format_timestamp_safe(y, sizeof(y), le64toh(f->header->tail_entry_realtime)), le64toh(f->header->tail_entry_realtime),
-               format_timespan(z, sizeof(z), le64toh(f->header->tail_entry_monotonic), USEC_PER_MSEC), le64toh(f->header->tail_entry_monotonic),
+               FORMAT_TIMESTAMP_SAFE(le64toh(f->header->head_entry_realtime)), le64toh(f->header->head_entry_realtime),
+               FORMAT_TIMESTAMP_SAFE(le64toh(f->header->tail_entry_realtime)), le64toh(f->header->tail_entry_realtime),
+               FORMAT_TIMESPAN(le64toh(f->header->tail_entry_monotonic), USEC_PER_MSEC), le64toh(f->header->tail_entry_monotonic),
                le64toh(f->header->n_objects),
                le64toh(f->header->n_entries));
 
@@ -3363,7 +3355,7 @@ void journal_file_print_header(JournalFile *f) {
                        f->header->data_hash_chain_depth);
 
         if (fstat(f->fd, &st) >= 0)
-                printf("Disk usage: %s\n", format_bytes(bytes, sizeof(bytes), (uint64_t) st.st_blocks * 512ULL));
+                printf("Disk usage: %s\n", FORMAT_BYTES((uint64_t) st.st_blocks * 512ULL));
 }
 
 static int journal_file_warn_btrfs(JournalFile *f) {
@@ -3468,7 +3460,6 @@ int journal_file_open(
         if (DEBUG_LOGGING) {
                 static int last_seal = -1, last_compress = -1, last_keyed_hash = -1;
                 static uint64_t last_bytes = UINT64_MAX;
-                char bytes[FORMAT_BYTES_MAX];
 
                 if (last_seal != f->seal ||
                     last_keyed_hash != f->keyed_hash ||
@@ -3477,7 +3468,7 @@ int journal_file_open(
 
                         log_debug("Journal effective settings seal=%s keyed_hash=%s compress=%s compress_threshold_bytes=%s",
                                   yes_no(f->seal), yes_no(f->keyed_hash), yes_no(JOURNAL_FILE_COMPRESS(f)),
-                                  format_bytes(bytes, sizeof bytes, f->compress_threshold_bytes));
+                                  FORMAT_BYTES(f->compress_threshold_bytes));
                         last_seal = f->seal;
                         last_keyed_hash = f->keyed_hash;
                         last_compress = JOURNAL_FILE_COMPRESS(f);
@@ -3977,7 +3968,6 @@ void journal_reset_metrics(JournalMetrics *m) {
 }
 
 void journal_default_metrics(JournalMetrics *m, int fd) {
-        char a[FORMAT_BYTES_MAX], b[FORMAT_BYTES_MAX], c[FORMAT_BYTES_MAX], d[FORMAT_BYTES_MAX], e[FORMAT_BYTES_MAX];
         struct statvfs ss;
         uint64_t fs_size = 0;
 
@@ -4047,11 +4037,11 @@ void journal_default_metrics(JournalMetrics *m, int fd) {
                 m->n_max_files = DEFAULT_N_MAX_FILES;
 
         log_debug("Fixed min_use=%s max_use=%s max_size=%s min_size=%s keep_free=%s n_max_files=%" PRIu64,
-                  format_bytes(a, sizeof(a), m->min_use),
-                  format_bytes(b, sizeof(b), m->max_use),
-                  format_bytes(c, sizeof(c), m->max_size),
-                  format_bytes(d, sizeof(d), m->min_size),
-                  format_bytes(e, sizeof(e), m->keep_free),
+                  FORMAT_BYTES(m->min_use),
+                  FORMAT_BYTES(m->max_use),
+                  FORMAT_BYTES(m->max_size),
+                  FORMAT_BYTES(m->min_size),
+                  FORMAT_BYTES(m->keep_free),
                   m->n_max_files);
 }
 
index 494a54d33b16d761ccdf93573c0d1d858cd84f94..6d761b78ebd45653cc17b4c216d6c47a66c8d74f 100644 (file)
@@ -131,7 +131,6 @@ int journal_directory_vacuum(
         _cleanup_closedir_ DIR *d = NULL;
         struct vacuum_info *list = NULL;
         usec_t retention_limit = 0;
-        char sbytes[FORMAT_BYTES_MAX];
         struct dirent *de;
         int r;
 
@@ -148,7 +147,6 @@ int journal_directory_vacuum(
                 return -errno;
 
         FOREACH_DIRENT_ALL(de, d, r = -errno; goto finish) {
-
                 unsigned long long seqnum = 0, realtime;
                 _cleanup_free_ char *p = NULL;
                 sd_id128_t seqnum_id;
@@ -254,7 +252,7 @@ int journal_directory_vacuum(
                         if (r >= 0) {
 
                                 log_full(verbose ? LOG_INFO : LOG_DEBUG,
-                                         "Deleted empty archived journal %s/%s (%s).", directory, p, format_bytes(sbytes, sizeof(sbytes), size));
+                                         "Deleted empty archived journal %s/%s (%s).", directory, p, FORMAT_BYTES(size));
 
                                 freed += size;
                         } else if (r != -ENOENT)
@@ -296,7 +294,8 @@ int journal_directory_vacuum(
 
                 r = unlinkat_deallocate(dirfd(d), list[i].filename, 0);
                 if (r >= 0) {
-                        log_full(verbose ? LOG_INFO : LOG_DEBUG, "Deleted archived journal %s/%s (%s).", directory, list[i].filename, format_bytes(sbytes, sizeof(sbytes), list[i].usage));
+                        log_full(verbose ? LOG_INFO : LOG_DEBUG, "Deleted archived journal %s/%s (%s).",
+                                 directory, list[i].filename, FORMAT_BYTES(list[i].usage));
                         freed += list[i].usage;
 
                         if (list[i].usage < sum)
@@ -318,7 +317,8 @@ finish:
                 free(list[i].filename);
         free(list);
 
-        log_full(verbose ? LOG_INFO : LOG_DEBUG, "Vacuuming done, freed %s of archived journals from %s.", format_bytes(sbytes, sizeof(sbytes), freed), directory);
+        log_full(verbose ? LOG_INFO : LOG_DEBUG, "Vacuuming done, freed %s of archived journals from %s.",
+                 FORMAT_BYTES(freed), directory);
 
         return r;
 }
index 5728c537bc603059fe65a7aa5bfe7e902ec38b00..e2be01d375fe10e66c03308f1a0f780f87cb44fd 100644 (file)
@@ -190,7 +190,7 @@ static bool same_field(const void *_a, size_t s, const void *_b, size_t t) {
                         return true;
         }
 
-        assert_not_reached("\"=\" not found");
+        assert_not_reached();
 }
 
 static Match *match_new(Match *p, MatchType t) {
index eb3459e27eac8d958f483c40d363edb5be2a1fcc..f222bf30212f6278ddb8f4758945688a7ae645c2 100644 (file)
@@ -68,7 +68,7 @@ static char* make_buf(size_t count, const char *type) {
                 random_bytes(buf + 8*step, step);
                 memzero(buf + 9*step, step);
         } else
-                assert_not_reached("here");
+                assert_not_reached();
 
         return buf;
 }
index e9abfef0fc9376b2cbc00e87d0bb92076ba42318..8eb9ca88f70b4a22e689ca123733507ff6f228ff 100644 (file)
@@ -57,9 +57,6 @@ int main(int argc, char *argv[]) {
         JournalFile *f;
         const char *verification_key = argv[1];
         usec_t from = 0, to = 0, total = 0;
-        char a[FORMAT_TIMESTAMP_MAX];
-        char b[FORMAT_TIMESTAMP_MAX];
-        char c[FORMAT_TIMESPAN_MAX];
         struct stat st;
         uint64_t p;
 
@@ -105,9 +102,9 @@ int main(int argc, char *argv[]) {
 
         if (verification_key && JOURNAL_HEADER_SEALED(f->header))
                 log_info("=> Validated from %s to %s, %s missing",
-                         format_timestamp(a, sizeof(a), from),
-                         format_timestamp(b, sizeof(b), to),
-                         format_timespan(c, sizeof(c), total > to ? total - to : 0, 0));
+                         FORMAT_TIMESTAMP(from),
+                         FORMAT_TIMESTAMP(to),
+                         FORMAT_TIMESPAN(total > to ? total - to : 0, 0));
 
         (void) journal_file_close(f);
 
index f6fff204f65aa971655fddf8d977e4462db5b294..d127443c4c0f9b8518743c91c1965b1cae1c131b 100644 (file)
@@ -585,8 +585,8 @@ _public_ int sd_session_get_class(const char *session, char **class) {
 
 _public_ int sd_session_get_desktop(const char *session, char **desktop) {
         _cleanup_free_ char *escaped = NULL;
-        char *t;
         int r;
+        ssize_t l;
 
         assert_return(desktop, -EINVAL);
 
@@ -594,11 +594,9 @@ _public_ int sd_session_get_desktop(const char *session, char **desktop) {
         if (r < 0)
                 return r;
 
-        r = cunescape(escaped, 0, &t);
-        if (r < 0)
-                return r;
-
-        *desktop = t;
+        l = cunescape(escaped, 0, desktop);
+        if (l < 0)
+                return l;
         return 0;
 }
 
@@ -1001,7 +999,7 @@ _public_ int sd_login_monitor_new(const char *category, sd_login_monitor **m) {
 
 _public_ sd_login_monitor* sd_login_monitor_unref(sd_login_monitor *m) {
         if (m)
-                close_nointr(MONITOR_TO_FD(m));
+                (void) close_nointr(MONITOR_TO_FD(m));
 
         return NULL;
 }
index 473d74b01a157939c86192816db52eb846c68c58..c4dc4e67dd5f4680f51887b83e09a47d743d974d 100644 (file)
@@ -1163,7 +1163,7 @@ int sd_netlink_message_enter_container(sd_netlink_message *m, unsigned short typ
                         break;
                 }
                 default:
-                        assert_not_reached("sd-netlink: invalid type system union type");
+                        assert_not_reached();
                 }
         } else
                 return -EINVAL;
index b6de545fe26fc6506dd5ab6dda02f6976256581b..76b4ccaa960ae28f4cd50f2e4591a6c026997a32 100644 (file)
@@ -92,7 +92,7 @@ void netlink_slot_disconnect(sd_netlink_slot *slot, bool unref) {
 
                 break;
         default:
-                assert_not_reached("Wut? Unknown slot type?");
+                assert_not_reached();
         }
 
         slot->type = _NETLINK_SLOT_INVALID;
index e771b95e0848bf5064d3592a4a94306d21766b7a..a5a2f4424ffcfc92aba2163775a545e606c1af4f 100644 (file)
@@ -288,7 +288,7 @@ int sd_rtnl_message_new_nexthop(sd_netlink *rtnl, sd_netlink_message **ret,
                 assert_return(IN_SET(nh_family, AF_UNSPEC, AF_INET, AF_INET6), -EINVAL);
                 break;
         default:
-                assert_not_reached("Invalid message type.");
+                assert_not_reached();
         }
         assert_return(ret, -EINVAL);
 
index 7273a77156a1dd3128a996bce6f3e1db73971cb1..ee93dae9e3a79965bc1331b1542285286cc9ad42 100644 (file)
@@ -444,7 +444,7 @@ _public_ int sd_network_monitor_new(sd_network_monitor **m, const char *category
 
 _public_ sd_network_monitor* sd_network_monitor_unref(sd_network_monitor *m) {
         if (m)
-                close_nointr(MONITOR_TO_FD(m));
+                (void) close_nointr(MONITOR_TO_FD(m));
 
         return NULL;
 }
index ee973c0692278444cfb45b868819ed659da879f4..c8af16a91811205fe06bc98222935852fb434d6b 100644 (file)
@@ -397,7 +397,7 @@ static int handle_request(int out_fd, const Packet *packet, size_t length) {
                  return -ECONNRESET;
 
         default:
-                assert_not_reached("Unknown request");
+                assert_not_reached();
         }
 
         return 0;
@@ -661,7 +661,7 @@ static int complete_query(sd_resolve *resolve, sd_resolve_query *q) {
                 break;
 
         default:
-                assert_not_reached("Cannot complete unknown query type");
+                assert_not_reached();
         }
 
         resolve->current = NULL;
index b973dfd90d24b9e2d9b0d45a2e56ac1cb31a9b45..647bd1e381d6f6dc577a77ca2e53af82ad5a4783 100644 (file)
@@ -99,7 +99,7 @@ int main(int argc, char *argv[]) {
                 }
                 if (r < 0) {
                         log_error_errno(r, "sd_resolve_wait(): %m");
-                        assert_not_reached("sd_resolve_wait() failed");
+                        assert_not_reached();
                 }
         }
 
index 89028aaa6bf2a02cced695aba50e045c1022d959..1d6487fa40846bac523f82a290f52478771b349b 100644 (file)
@@ -16,4 +16,5 @@ Name: libudev
 Description: Library to access udev device information
 Version: {{PROJECT_VERSION}}
 Libs: -L${libdir} -ludev
+Libs.private: -lrt -pthread
 Cflags: -I${includedir}
index 61e7cc20a6abbc46718a2058262241d5d753349f..130374d14fb0f743f8abc9c4be9fab60fbbcb40a 100644 (file)
@@ -19,10 +19,10 @@ libudev_sources = files(
 libudev_includes = [includes, include_directories('.')]
 
 libudev_sym = files('libudev.sym')
-libudev_sym_path = join_paths(meson.current_source_dir(), 'libudev.sym')
+libudev_sym_path = meson.current_source_dir() / 'libudev.sym'
 
 install_headers('libudev.h')
-libudev_h_path = join_paths(meson.current_source_dir(), 'libudev.h')
+libudev_h_path = meson.current_source_dir() / 'libudev.h'
 
 libudev_basic = static_library(
         'udev-basic',
index a7510567954145197b634246824c32f31a862738..354ded3a2b495e818f15e23a37b91d450ebb5778 100644 (file)
@@ -445,7 +445,7 @@ static int parse_args(int argc, char *argv[], const char **syspath, const char *
                         return -EINVAL;
 
                 default:
-                        assert_not_reached("Unhandled option code.");
+                        assert_not_reached();
                 }
 
         return 1;
index d2f0566dbc5214cc709c0b01dd7688d449c17b9a..d48f0b421688ba31a4e928ec074d72312299f333 100644 (file)
@@ -691,7 +691,7 @@ int find_language_fallback(const char *lang, char **language) {
                 }
         }
 
-        assert_not_reached("should not be here");
+        assert_not_reached();
 }
 
 int x11_convert_to_vconsole(Context *c) {
index 548ac8eb2c357ce330516b4f5de1fac30d2b86c3..0de3532f9786258ab7468348afc4f8d4a8ad4feb 100644 (file)
@@ -293,7 +293,7 @@ static int list_x11_keymaps(int argc, char **argv, void *userdata) {
         else if (streq(argv[0], "list-x11-keymap-options"))
                 look_for = OPTIONS;
         else
-                assert_not_reached("Wrong parameter");
+                assert_not_reached();
 
         for (;;) {
                 _cleanup_free_ char *line = NULL;
@@ -474,7 +474,7 @@ static int parse_argv(int argc, char *argv[]) {
                         return -EINVAL;
 
                 default:
-                        assert_not_reached("Unhandled option");
+                        assert_not_reached();
                 }
 
         return 1;
index 757d4457e93ec2152e93bc57d84e6bfc3e7df06f..a2ff2a98736ff48331a0dc80bf1933ec3c3400b2 100644 (file)
@@ -20,8 +20,8 @@ endif
 # If you know a way that allows the same variables to be used
 # in sources list and concatenated to a string for test_env,
 # let me know.
-kbd_model_map = join_paths(meson.current_source_dir(), 'kbd-model-map')
-language_fallback_map = join_paths(meson.current_source_dir(), 'language-fallback-map')
+kbd_model_map = meson.current_source_dir() / 'kbd-model-map'
+language_fallback_map = meson.current_source_dir() / 'language-fallback-map'
 
 if conf.get('ENABLE_LOCALED') == 1
         install_data('kbd-model-map',
index e871628b9a5d8ade9004580a03b9e6502de146cc..ff5a5d06f516cf76f0177bd0029e737e4e4bd2b7 100644 (file)
@@ -256,7 +256,7 @@ static int parse_argv(int argc, char *argv[]) {
                         return -EINVAL;
 
                 default:
-                        assert_not_reached("Unhandled option");
+                        assert_not_reached();
                 }
 
         if (arg_action == ACTION_INHIBIT && optind == argc)
index cbb6518f4d2031d6ac8fed65c5d8ada59162b63b..846a31012eba036d47af7b6151becbbfaf568e67 100644 (file)
@@ -450,9 +450,6 @@ static int print_session_status_info(sd_bus *bus, const char *path, bool *new_li
 
         _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
         _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL;
-        char since1[FORMAT_TIMESTAMP_RELATIVE_MAX];
-        char since2[FORMAT_TIMESTAMP_MAX];
-        const char *s1, *s2;
         SessionStatusInfo i = {};
         int r;
 
@@ -472,13 +469,10 @@ static int print_session_status_info(sd_bus *bus, const char *path, bool *new_li
         else
                 printf("%"PRIu32"\n", i.uid);
 
-        s1 = format_timestamp_relative(since1, sizeof(since1), i.timestamp.realtime);
-        s2 = format_timestamp(since2, sizeof(since2), i.timestamp.realtime);
-
-        if (s1)
-                printf("\t   Since: %s; %s\n", s2, s1);
-        else if (s2)
-                printf("\t   Since: %s\n", s2);
+        if (i.timestamp.realtime > 0 && i.timestamp.realtime < USEC_INFINITY)
+                printf("\t   Since: %s; %s\n",
+                       FORMAT_TIMESTAMP(i.timestamp.realtime),
+                       FORMAT_TIMESTAMP_RELATIVE(i.timestamp.realtime));
 
         if (i.leader > 0) {
                 _cleanup_free_ char *t = NULL;
@@ -581,9 +575,6 @@ static int print_user_status_info(sd_bus *bus, const char *path, bool *new_line)
 
         _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
         _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL;
-        char since1[FORMAT_TIMESTAMP_RELATIVE_MAX];
-        char since2[FORMAT_TIMESTAMP_MAX];
-        const char *s1, *s2;
         _cleanup_(user_status_info_clear) UserStatusInfo i = {};
         int r;
 
@@ -601,13 +592,10 @@ static int print_user_status_info(sd_bus *bus, const char *path, bool *new_line)
         else
                 printf("%"PRIu32"\n", i.uid);
 
-        s1 = format_timestamp_relative(since1, sizeof(since1), i.timestamp.realtime);
-        s2 = format_timestamp(since2, sizeof(since2), i.timestamp.realtime);
-
-        if (s1)
-                printf("\t   Since: %s; %s\n", s2, s1);
-        else if (s2)
-                printf("\t   Since: %s\n", s2);
+        if (i.timestamp.realtime > 0 && i.timestamp.realtime < USEC_INFINITY)
+                printf("\t   Since: %s; %s\n",
+                       FORMAT_TIMESTAMP(i.timestamp.realtime),
+                       FORMAT_TIMESTAMP_RELATIVE(i.timestamp.realtime));
 
         if (!isempty(i.state))
                 printf("\t   State: %s\n", i.state);
@@ -1424,7 +1412,7 @@ static int parse_argv(int argc, char *argv[]) {
                         return -EINVAL;
 
                 default:
-                        assert_not_reached("Unhandled option");
+                        assert_not_reached();
                 }
 
         return 1;
index a2eb4c5269fb3f47844315f48d1ef7cf2aa4ab7c..7fb811463938a6b1b5e5e7a2556e462c3149ab13 100644 (file)
@@ -279,12 +279,28 @@ static int button_dispatch(sd_event_source *s, int fd, uint32_t revents, void *u
                 }
 
         } else if (ev.type == EV_KEY && ev.value == 0) {
-                if (ev.code == KEY_RESTART) {
-                        if (b->manager->reboot_key_long_press_event_source) {
+
+                switch (ev.code) {
+
+                case KEY_POWER:
+                case KEY_POWER2:
+                        if (b->manager->power_key_long_press_event_source) {
                                 /* Long press event timer is still pending and key release
                                    event happened.  This means that key press duration was
                                    insufficient to trigger a long press event
                                 */
+                                log_struct(LOG_INFO,
+                                           LOG_MESSAGE("Power key pressed short."),
+                                           "MESSAGE_ID=" SD_MESSAGE_POWER_KEY_STR);
+
+                                b->manager->power_key_long_press_event_source = sd_event_source_unref(b->manager->power_key_long_press_event_source);
+
+                                manager_handle_action(b->manager, INHIBIT_HANDLE_POWER_KEY, b->manager->handle_power_key, b->manager->power_key_ignore_inhibited, true);
+                        }
+                        break;
+
+                case KEY_RESTART:
+                        if (b->manager->reboot_key_long_press_event_source) {
                                 log_struct(LOG_INFO,
                                            LOG_MESSAGE("Reboot key pressed short."),
                                            "MESSAGE_ID=" SD_MESSAGE_REBOOT_KEY_STR);
@@ -293,6 +309,30 @@ static int button_dispatch(sd_event_source *s, int fd, uint32_t revents, void *u
 
                                 manager_handle_action(b->manager, INHIBIT_HANDLE_REBOOT_KEY, b->manager->handle_reboot_key, b->manager->reboot_key_ignore_inhibited, true);
                         }
+                        break;
+
+                case KEY_SLEEP:
+                        if (b->manager->suspend_key_long_press_event_source) {
+                                log_struct(LOG_INFO,
+                                           LOG_MESSAGE("Suspend key pressed short."),
+                                           "MESSAGE_ID=" SD_MESSAGE_SUSPEND_KEY_STR);
+
+                                b->manager->suspend_key_long_press_event_source = sd_event_source_unref(b->manager->suspend_key_long_press_event_source);
+
+                                manager_handle_action(b->manager, INHIBIT_HANDLE_SUSPEND_KEY, b->manager->handle_suspend_key, b->manager->suspend_key_ignore_inhibited, true);
+                        }
+                        break;
+                case KEY_SUSPEND:
+                        if (b->manager->hibernate_key_long_press_event_source) {
+                                log_struct(LOG_INFO,
+                                           LOG_MESSAGE("Hibernate key pressed short."),
+                                           "MESSAGE_ID=" SD_MESSAGE_HIBERNATE_KEY_STR);
+
+                                b->manager->hibernate_key_long_press_event_source = sd_event_source_unref(b->manager->hibernate_key_long_press_event_source);
+
+                                manager_handle_action(b->manager, INHIBIT_HANDLE_HIBERNATE_KEY, b->manager->handle_hibernate_key, b->manager->hibernate_key_ignore_inhibited, true);
+                        }
+                        break;
                 }
 
         } else if (ev.type == EV_SW && ev.value > 0) {
index 19c3f9bd6e251c9053409e700a7bc7f7d31e5d27..ccda0bdec4d187e4f10fc3171aa3c4618155e807 100644 (file)
@@ -1791,6 +1791,9 @@ static int verify_shutdown_creds(
         assert(message);
         assert(w >= 0);
         assert(w <= _INHIBIT_WHAT_MAX);
+        assert(action);
+        assert(action_multiple_sessions);
+        assert(action_ignore_inhibit);
 
         r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_EUID, &creds);
         if (r < 0)
@@ -1808,7 +1811,7 @@ static int verify_shutdown_creds(
         blocked = manager_is_inhibited(m, w, INHIBIT_BLOCK, NULL, false, true, uid, NULL);
         interactive = flags & SD_LOGIND_INTERACTIVE;
 
-        if (multiple_sessions && action_multiple_sessions) {
+        if (multiple_sessions) {
                 r = bus_verify_polkit_async(message, CAP_SYS_BOOT, action_multiple_sessions, NULL, interactive, UID_INVALID, &m->polkit_registry, error);
                 if (r < 0)
                         return r;
@@ -1822,16 +1825,14 @@ static int verify_shutdown_creds(
                         return sd_bus_error_setf(error, SD_BUS_ERROR_ACCESS_DENIED,
                                                  "Access denied to root due to active block inhibitor");
 
-                if (action_ignore_inhibit) {
-                        r = bus_verify_polkit_async(message, CAP_SYS_BOOT, action_ignore_inhibit, NULL, interactive, UID_INVALID, &m->polkit_registry, error);
-                        if (r < 0)
-                                return r;
-                        if (r == 0)
-                                return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
-                }
+                r = bus_verify_polkit_async(message, CAP_SYS_BOOT, action_ignore_inhibit, NULL, interactive, UID_INVALID, &m->polkit_registry, error);
+                if (r < 0)
+                        return r;
+                if (r == 0)
+                        return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
         }
 
-        if (!multiple_sessions && !blocked && action) {
+        if (!multiple_sessions && !blocked) {
                 r = bus_verify_polkit_async(message, CAP_SYS_BOOT, action, NULL, interactive, UID_INVALID, &m->polkit_registry, error);
                 if (r < 0)
                         return r;
@@ -2140,7 +2141,7 @@ static int manager_scheduled_shutdown_handler(
         else if (streq(m->scheduled_shutdown_type, "halt"))
                 target = SPECIAL_HALT_TARGET;
         else
-                assert_not_reached("unexpected shutdown type");
+                assert_not_reached();
 
         /* Don't allow multiple jobs being executed at the same time */
         if (m->action_what > 0) {
index 57198ce65293f0cc0852172e15af52810207ed67..f8048f6d23b7080947a401f4d3c8c60587c1b763 100644 (file)
@@ -209,18 +209,11 @@ void inhibitor_stop(Inhibitor *i) {
 }
 
 int inhibitor_load(Inhibitor *i) {
-
-        _cleanup_free_ char
-                *what = NULL,
-                *uid = NULL,
-                *pid = NULL,
-                *who = NULL,
-                *why = NULL,
-                *mode = NULL;
-
+        _cleanup_free_ char *what = NULL, *uid = NULL, *pid = NULL, *who = NULL, *why = NULL, *mode = NULL;
         InhibitWhat w;
         InhibitMode mm;
         char *cc;
+        ssize_t l;
         int r;
 
         r = parse_env_file(NULL, i->state_file,
@@ -255,17 +248,17 @@ int inhibitor_load(Inhibitor *i) {
         }
 
         if (who) {
-                r = cunescape(who, 0, &cc);
-                if (r < 0)
-                        return log_oom();
+                l = cunescape(who, 0, &cc);
+                if (l < 0)
+                        return log_debug_errno(l, "Failed to unescape \"who\" of inhibitor: %m");
 
                 free_and_replace(i->who, cc);
         }
 
         if (why) {
-                r = cunescape(why, 0, &cc);
-                if (r < 0)
-                        return log_oom();
+                l = cunescape(why, 0, &cc);
+                if (l < 0)
+                        return log_debug_errno(l, "Failed to unescape \"why\" of inhibitor: %m");
 
                 free_and_replace(i->why, cc);
         }
index f2adb969d4e4119fd9a9e9d12c948f81b4b26932..1c4d543889edba318605562954d0fa2837d500e8 100644 (file)
@@ -141,7 +141,7 @@ static int session_device_open(SessionDevice *sd, bool active) {
                          * that so fail at all times and let caller retry in inactive state. */
                         r = sd_drmsetmaster(fd);
                         if (r < 0) {
-                                close_nointr(fd);
+                                (void) close_nointr(fd);
                                 return r;
                         }
                 } else
index a2c468e8dd0c1b73431ce0cec259670eecb010d3..1c8d84329f87081dc05fe649e41217901acd642d 100644 (file)
@@ -867,13 +867,10 @@ void user_update_last_session_timer(User *u) {
         if (r < 0)
                 log_warning_errno(r, "Failed to enqueue user stop event source, ignoring: %m");
 
-        if (DEBUG_LOGGING) {
-                char s[FORMAT_TIMESPAN_MAX];
-
+        if (DEBUG_LOGGING)
                 log_debug("Last session of user '%s' logged out, terminating user context in %s.",
                           u->user_record->user_name,
-                          format_timespan(s, sizeof(s), user_stop_delay, USEC_PER_MSEC));
-        }
+                          FORMAT_TIMESPAN(user_stop_delay, USEC_PER_MSEC));
 }
 
 static const char* const user_state_table[_USER_STATE_MAX] = {
index dfbbb641f3ba61d310173b153f66a4e93d0a6850..553383647336a47235d047b495593f06faecd0a3 100644 (file)
@@ -58,7 +58,6 @@ bool logind_wall_tty_filter(const char *tty, void *userdata) {
 }
 
 static int warn_wall(Manager *m, usec_t n) {
-        char date[FORMAT_TIMESTAMP_MAX] = {};
         _cleanup_free_ char *l = NULL, *username = NULL;
         usec_t left;
         int r;
@@ -75,7 +74,7 @@ static int warn_wall(Manager *m, usec_t n) {
                      isempty(m->wall_message) ? "" : "\n",
                      m->scheduled_shutdown_type,
                      left ? "at " : "NOW",
-                     left ? format_timestamp(date, sizeof(date), m->scheduled_shutdown_timeout) : "");
+                     left ? FORMAT_TIMESTAMP(m->scheduled_shutdown_timeout) : "");
         if (r < 0) {
                 log_oom();
                 return 0;
index f8bd17eefecaafe87fd6d587f769003677e93151..1b643d52ca95a8e95f52818ff6cf2252e7ff3db8 100644 (file)
@@ -705,7 +705,11 @@ _public_ PAM_EXTERN int pam_sm_open_session(
          * "systemd-user" we simply set XDG_RUNTIME_DIR and
          * leave. */
 
-        (void) pam_get_item(handle, PAM_SERVICE, (const void**) &service);
+        r = pam_get_item(handle, PAM_SERVICE, (const void**) &service);
+        if (!IN_SET(r, PAM_BAD_ITEM, PAM_SUCCESS)) {
+                pam_syslog(handle, LOG_ERR, "Failed to get PAM service: %s", pam_strerror(handle, r));
+                return r;
+        }
         if (streq_ptr(service, "systemd-user")) {
                 char rt[STRLEN("/run/user/") + DECIMAL_STR_MAX(uid_t)];
 
@@ -719,10 +723,26 @@ _public_ PAM_EXTERN int pam_sm_open_session(
 
         /* Otherwise, we ask logind to create a session for us */
 
-        (void) pam_get_item(handle, PAM_XDISPLAY, (const void**) &display);
-        (void) pam_get_item(handle, PAM_TTY, (const void**) &tty);
-        (void) pam_get_item(handle, PAM_RUSER, (const void**) &remote_user);
-        (void) pam_get_item(handle, PAM_RHOST, (const void**) &remote_host);
+        r = pam_get_item(handle, PAM_XDISPLAY, (const void**) &display);
+        if (!IN_SET(r, PAM_BAD_ITEM, PAM_SUCCESS)) {
+                pam_syslog(handle, LOG_ERR, "Failed to get PAM XDISPLAY: %s", pam_strerror(handle, r));
+                return r;
+        }
+        r = pam_get_item(handle, PAM_TTY, (const void**) &tty);
+        if (!IN_SET(r, PAM_BAD_ITEM, PAM_SUCCESS)) {
+                pam_syslog(handle, LOG_ERR, "Failed to get PAM TTY: %s", pam_strerror(handle, r));
+                return r;
+        }
+        r = pam_get_item(handle, PAM_RUSER, (const void**) &remote_user);
+        if (!IN_SET(r, PAM_BAD_ITEM, PAM_SUCCESS)) {
+                pam_syslog(handle, LOG_ERR, "Failed to get PAM RUSER: %s", pam_strerror(handle, r));
+                return r;
+        }
+        r = pam_get_item(handle, PAM_RHOST, (const void**) &remote_host);
+        if (!IN_SET(r, PAM_BAD_ITEM, PAM_SUCCESS)) {
+                pam_syslog(handle, LOG_ERR, "Failed to get PAM RHOST: %s", pam_strerror(handle, r));
+                return r;
+        }
 
         seat = getenv_harder(handle, "XDG_SEAT", NULL);
         cvtnr = getenv_harder(handle, "XDG_VTNR", NULL);
@@ -789,11 +809,31 @@ _public_ PAM_EXTERN int pam_sm_open_session(
 
         remote = !isempty(remote_host) && !is_localhost(remote_host);
 
-        (void) pam_get_data(handle, "systemd.memory_max", (const void **)&memory_max);
-        (void) pam_get_data(handle, "systemd.tasks_max",  (const void **)&tasks_max);
-        (void) pam_get_data(handle, "systemd.cpu_weight", (const void **)&cpu_weight);
-        (void) pam_get_data(handle, "systemd.io_weight",  (const void **)&io_weight);
-        (void) pam_get_data(handle, "systemd.runtime_max_sec", (const void **)&runtime_max_sec);
+        r = pam_get_data(handle, "systemd.memory_max", (const void **)&memory_max);
+        if (!IN_SET(r, PAM_SUCCESS, PAM_NO_MODULE_DATA)) {
+                pam_syslog(handle, LOG_ERR, "Failed to get PAM systemd.memory_max data: %s", pam_strerror(handle, r));
+                return r;
+        }
+        r = pam_get_data(handle, "systemd.tasks_max",  (const void **)&tasks_max);
+        if (!IN_SET(r, PAM_SUCCESS, PAM_NO_MODULE_DATA)) {
+                pam_syslog(handle, LOG_ERR, "Failed to get PAM systemd.tasks_max data: %s", pam_strerror(handle, r));
+                return r;
+        }
+        r = pam_get_data(handle, "systemd.cpu_weight", (const void **)&cpu_weight);
+        if (!IN_SET(r, PAM_SUCCESS, PAM_NO_MODULE_DATA)) {
+                pam_syslog(handle, LOG_ERR, "Failed to get PAM systemd.cpu_weight data: %s", pam_strerror(handle, r));
+                return r;
+        }
+        r = pam_get_data(handle, "systemd.io_weight",  (const void **)&io_weight);
+        if (!IN_SET(r, PAM_SUCCESS, PAM_NO_MODULE_DATA)) {
+                pam_syslog(handle, LOG_ERR, "Failed to get PAM systemd.io_weight data: %s", pam_strerror(handle, r));
+                return r;
+        }
+        r = pam_get_data(handle, "systemd.runtime_max_sec", (const void **)&runtime_max_sec);
+        if (!IN_SET(r, PAM_SUCCESS, PAM_NO_MODULE_DATA)) {
+                pam_syslog(handle, LOG_ERR, "Failed to get PAM systemd.runtime_max_sec data: %s", pam_strerror(handle, r));
+                return r;
+        }
 
         /* Talk to logind over the message bus */
 
@@ -996,7 +1036,11 @@ _public_ PAM_EXTERN int pam_sm_close_session(
 
         /* Only release session if it wasn't pre-existing when we
          * tried to create it */
-        (void) pam_get_data(handle, "systemd.existing", &existing);
+        r = pam_get_data(handle, "systemd.existing", &existing);
+        if (!IN_SET(r, PAM_SUCCESS, PAM_NO_MODULE_DATA)) {
+                pam_syslog(handle, LOG_ERR, "Failed to get PAM systemd.existing data: %s", pam_strerror(handle, r));
+                return r;
+        }
 
         id = pam_getenv(handle, "XDG_SESSION_ID");
         if (id && !existing) {
index 07d72d214def188909aa17395d4e9edc5a9e03e6..a1087ed31c9965ae0dbe0b4a2cc4691ef7c09f8f 100644 (file)
@@ -207,7 +207,7 @@ static int run(int argc, char *argv[]) {
                 return do_mount(argv[2]);
         if (streq(argv[1], "stop"))
                 return do_umount(argv[2]);
-        assert_not_reached("Unknown verb!");
+        assert_not_reached();
 }
 
 DEFINE_MAIN_FUNCTION(run);
index 5af6bfeafe4af3b40668313505b956670a75b0ad..0f8bc43ab55590014e6eb87d6aee7eb13df8c307 100644 (file)
@@ -110,7 +110,7 @@ static int parse_argv(int argc, char *argv[]) {
                         return -EINVAL;
 
                 default:
-                        assert_not_reached("Unhandled option");
+                        assert_not_reached();
                 }
 
         if (optind < argc)
index beab50e3158fd17fe7f90df7b31b6acd4328d9f1..b4c251078ba8b60b7e7b49b0b16f04bcbe85e509 100644 (file)
@@ -507,10 +507,7 @@ static void machine_status_info_clear(MachineStatusInfo *info) {
 }
 
 static void print_machine_status_info(sd_bus *bus, MachineStatusInfo *i) {
-        char since1[FORMAT_TIMESTAMP_RELATIVE_MAX];
-        char since2[FORMAT_TIMESTAMP_MAX];
-        _cleanup_free_ char *addresses = NULL;
-        const char *s1, *s2;
+        _cleanup_free_ char *addresses = NULL, *s1 = NULL, *s2 = NULL;
         int ifi = -1;
 
         assert(bus);
@@ -523,12 +520,12 @@ static void print_machine_status_info(sd_bus *bus, MachineStatusInfo *i) {
         else
                 putchar('\n');
 
-        s1 = format_timestamp_relative(since1, sizeof(since1), i->timestamp.realtime);
-        s2 = format_timestamp(since2, sizeof(since2), i->timestamp.realtime);
+        s1 = strdup(strempty(FORMAT_TIMESTAMP_RELATIVE(i->timestamp.realtime)));
+        s2 = strdup(strempty(FORMAT_TIMESTAMP(i->timestamp.realtime)));
 
-        if (s1)
-                printf("\t   Since: %s; %s\n", s2, s1);
-        else if (s2)
+        if (!isempty(s1))
+                printf("\t   Since: %s; %s\n", strna(s2), s1);
+        else if (!isempty(s2))
                 printf("\t   Since: %s\n", s2);
 
         if (i->leader > 0) {
@@ -828,12 +825,6 @@ typedef struct ImageStatusInfo {
 } ImageStatusInfo;
 
 static void print_image_status_info(sd_bus *bus, ImageStatusInfo *i) {
-        char ts_relative[FORMAT_TIMESTAMP_RELATIVE_MAX];
-        char ts_absolute[FORMAT_TIMESTAMP_MAX];
-        char bs[FORMAT_BYTES_MAX];
-        char bs_exclusive[FORMAT_BYTES_MAX];
-        const char *s1, *s2, *s3, *s4;
-
         assert(bus);
         assert(i);
 
@@ -859,33 +850,29 @@ static void print_image_status_info(sd_bus *bus, ImageStatusInfo *i) {
                i->read_only ? "read-only" : "writable",
                i->read_only ? ansi_normal() : "");
 
-        s1 = format_timestamp_relative(ts_relative, sizeof(ts_relative), i->crtime);
-        s2 = format_timestamp(ts_absolute, sizeof(ts_absolute), i->crtime);
-        if (s1 && s2)
-                printf("\t Created: %s; %s\n", s2, s1);
-        else if (s2)
-                printf("\t Created: %s\n", s2);
-
-        s1 = format_timestamp_relative(ts_relative, sizeof(ts_relative), i->mtime);
-        s2 = format_timestamp(ts_absolute, sizeof(ts_absolute), i->mtime);
-        if (s1 && s2)
-                printf("\tModified: %s; %s\n", s2, s1);
-        else if (s2)
-                printf("\tModified: %s\n", s2);
-
-        s3 = format_bytes(bs, sizeof(bs), i->usage);
-        s4 = i->usage_exclusive != i->usage ? format_bytes(bs_exclusive, sizeof(bs_exclusive), i->usage_exclusive) : NULL;
-        if (s3 && s4)
-                printf("\t   Usage: %s (exclusive: %s)\n", s3, s4);
-        else if (s3)
-                printf("\t   Usage: %s\n", s3);
-
-        s3 = format_bytes(bs, sizeof(bs), i->limit);
-        s4 = i->limit_exclusive != i->limit ? format_bytes(bs_exclusive, sizeof(bs_exclusive), i->limit_exclusive) : NULL;
-        if (s3 && s4)
-                printf("\t   Limit: %s (exclusive: %s)\n", s3, s4);
-        else if (s3)
-                printf("\t   Limit: %s\n", s3);
+        if (i->crtime > 0 && i->crtime < USEC_INFINITY)
+                printf("\t Created: %s; %s\n",
+                       FORMAT_TIMESTAMP(i->crtime), FORMAT_TIMESTAMP_RELATIVE(i->crtime));
+
+        if (i->mtime > 0 && i->mtime < USEC_INFINITY)
+                printf("\tModified: %s; %s\n",
+                       FORMAT_TIMESTAMP(i->mtime), FORMAT_TIMESTAMP_RELATIVE(i->mtime));
+
+        if (i->usage != UINT64_MAX) {
+                if (i->usage_exclusive != i->usage && i->usage_exclusive != UINT64_MAX)
+                        printf("\t   Usage: %s (exclusive: %s)\n",
+                               FORMAT_BYTES(i->usage), FORMAT_BYTES(i->usage_exclusive));
+                else
+                        printf("\t   Usage: %s\n", FORMAT_BYTES(i->usage));
+        }
+
+        if (i->limit != UINT64_MAX) {
+                if (i->limit_exclusive != i->limit && i->limit_exclusive != UINT64_MAX)
+                        printf("\t   Limit: %s (exclusive: %s)\n",
+                               FORMAT_BYTES(i->limit), FORMAT_BYTES(i->limit_exclusive));
+                else
+                        printf("\t   Limit: %s\n", FORMAT_BYTES(i->limit));
+        }
 }
 
 static int show_image_info(sd_bus *bus, const char *path, bool *new_line) {
@@ -940,18 +927,14 @@ typedef struct PoolStatusInfo {
 } PoolStatusInfo;
 
 static void print_pool_status_info(sd_bus *bus, PoolStatusInfo *i) {
-        char bs[FORMAT_BYTES_MAX], *s;
-
         if (i->path)
                 printf("\t    Path: %s\n", i->path);
 
-        s = format_bytes(bs, sizeof(bs), i->usage);
-        if (s)
-                printf("\t   Usage: %s\n", s);
+        if (i->usage != UINT64_MAX)
+                printf("\t   Usage: %s\n", FORMAT_BYTES(i->usage));
 
-        s = format_bytes(bs, sizeof(bs), i->limit);
-        if (s)
-                printf("\t   Limit: %s\n", s);
+        if (i->limit != UINT64_MAX)
+                printf("\t   Limit: %s\n", FORMAT_BYTES(i->limit));
 }
 
 static int show_pool_info(sd_bus *bus) {
@@ -2409,7 +2392,6 @@ static int clean_images(int argc, char *argv[], void *userdata) {
         _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL, *reply = NULL;
         _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
         uint64_t usage, total = 0;
-        char fb[FORMAT_BYTES_MAX];
         sd_bus *bus = userdata;
         const char *name;
         unsigned c = 0;
@@ -2440,7 +2422,7 @@ static int clean_images(int argc, char *argv[], void *userdata) {
                         total = UINT64_MAX;
                 } else {
                         log_info("Removed image '%s'. Freed exclusive disk space: %s",
-                                 name, format_bytes(fb, sizeof(fb), usage));
+                                 name, FORMAT_BYTES(usage));
                         if (total != UINT64_MAX)
                                 total += usage;
                 }
@@ -2455,7 +2437,7 @@ static int clean_images(int argc, char *argv[], void *userdata) {
                 log_info("Removed %u images in total.", c);
         else
                 log_info("Removed %u images in total. Total freed exclusive disk space: %s.",
-                         c, format_bytes(fb, sizeof(fb), total));
+                         c, FORMAT_BYTES(total));
 
         return 0;
 }
@@ -2807,7 +2789,7 @@ static int parse_argv(int argc, char *argv[]) {
                         return -EINVAL;
 
                 default:
-                        assert_not_reached("Unhandled option");
+                        assert_not_reached();
                 }
         }
 
index 009d283acc6450c844b99c807e00e7e3dc6edaab..fc0b0f11ad9494d9ffefbced069d1ab3e7ad9080 100644 (file)
@@ -297,7 +297,7 @@ static int group_lookup_name(Manager *m, const char *name, gid_t *ret_gid, char
                 desc = mfree(desc);
 
         *ret_gid = converted_gid;
-        *ret_description = desc;
+        *ret_description = TAKE_PTR(desc);
         return 0;
 }
 
index b2a41a7e755025f67b7604b3acd1992ecfd1824f..eda847cb4a0292e93b15d4e8f7f357d7777ca8c8 100644 (file)
@@ -152,7 +152,7 @@ static int parse_argv(int argc, char *argv[]) {
                         return -EINVAL;
 
                 default:
-                        assert_not_reached("Unhandled option");
+                        assert_not_reached();
                 }
 
         return 1;
index c213c905a1aa627368c94570960ad2556b7264aa..b0de83b8d0365d63cf00d267eaf8eaf13d3532f8 100644 (file)
@@ -329,7 +329,7 @@ static int parse_argv(int argc, char *argv[]) {
                         return -EINVAL;
 
                 default:
-                        assert_not_reached("Unhandled option");
+                        assert_not_reached();
                 }
 
         if (arg_user && arg_transport != BUS_TRANSPORT_LOCAL)
@@ -1530,7 +1530,7 @@ static int run(int argc, char* argv[]) {
                 break;
 
         default:
-                assert_not_reached("Unexpected action.");
+                assert_not_reached();
         }
 
         return r;
index 1ac8bf01c5e37ec5606b909bdf075965f6235a5c..624b0a0b5dfda77e0d0b031336031ee939ccb34c 100644 (file)
@@ -157,7 +157,7 @@ static int parse_argv(int argc, char *argv[]) {
                         return -EINVAL;
 
                 default:
-                        assert_not_reached("Unhandled option");
+                        assert_not_reached();
                 }
 
         return 1;
index 4e137d7b9e2e93f81f859b5d637cbb86685221f5..2ea12c8d030e8f683d232c8d84ba4e22fe2a7325 100644 (file)
@@ -268,6 +268,12 @@ fuzzers += [
 ]
 
 tests += [
+        [['src/network/test-networkd-address.c'],
+         [libnetworkd_core,
+          libsystemd_network],
+         [],
+         network_includes],
+
         [['src/network/test-networkd-conf.c'],
          [libnetworkd_core,
           libsystemd_network],
index 6863257a58948099a218f778b50c9df73bceab34..0ed0df75799ae355488d0df2a45a81435285af1d 100644 (file)
@@ -58,7 +58,7 @@ static int netdev_fill_fou_tunnel_message(NetDev *netdev, sd_netlink_message **r
                 encap_type = FOU_ENCAP_GUE;
                 break;
         default:
-                assert_not_reached("invalid encap type");
+                assert_not_reached();
         }
 
         r = sd_netlink_message_append_u8(m, FOU_ATTR_TYPE, encap_type);
@@ -243,7 +243,7 @@ static int netdev_fou_tunnel_verify(NetDev *netdev, const char *filename) {
                                                       filename);
                 break;
         default:
-                assert_not_reached("Invalid fou encap type");
+                assert_not_reached();
         }
 
         if (t->peer_family == AF_UNSPEC && t->peer_port > 0)
index 53534d4873410876ca0009a38f960f6d42970376..c3ab6aecdb8d3a6d3bf8d4ae340e689d79d188cb 100644 (file)
@@ -528,7 +528,7 @@ int netdev_join(NetDev *netdev, Link *link, link_netlink_message_handler_t callb
                         return r;
                 break;
         default:
-                assert_not_reached("Cannot join independent netdev");
+                assert_not_reached();
         }
 
         return 0;
index 23718081b90bc5c513fae83c6afd44061ec3243a..f27a1e4335144dfd6bce185daa66fbff1868d461 100644 (file)
@@ -128,7 +128,7 @@ static int netdev_gre_erspan_fill_message_create(NetDev *netdev, Link *link, sd_
                 t = GRETAP(netdev);
                 break;
         default:
-                assert_not_reached("invalid netdev kind");
+                assert_not_reached();
         }
 
         assert(t);
@@ -457,7 +457,7 @@ static int netdev_tunnel_verify(NetDev *netdev, const char *filename) {
                 t = ERSPAN(netdev);
                 break;
         default:
-                assert_not_reached("Invalid tunnel kind");
+                assert_not_reached();
         }
 
         assert(t);
@@ -722,7 +722,7 @@ static void ipip_sit_init(NetDev *n) {
                 t = SIT(n);
                 break;
         default:
-                assert_not_reached("invalid netdev kind");
+                assert_not_reached();
         }
 
         assert(t);
@@ -763,7 +763,7 @@ static void gre_erspan_init(NetDev *n) {
                 t = GRETAP(n);
                 break;
         default:
-                assert_not_reached("invalid netdev kind");
+                assert_not_reached();
         }
 
         assert(t);
index 9bbfe177b17a4a00aee95864e9ae1550d8531f03..09a19192bcf698c3519a1de222b01130fd3bba6d 100644 (file)
@@ -2121,16 +2121,14 @@ static int link_status_one(
         }
 
         if (info->has_bitrates) {
-                char tx[FORMAT_BYTES_MAX], rx[FORMAT_BYTES_MAX];
-
                 r = table_add_many(table,
                                    TABLE_EMPTY,
                                    TABLE_STRING, "Bit Rate (Tx/Rx):");
                 if (r < 0)
                         return table_log_add_error(r);
                 r = table_add_cell_stringf(table, NULL, "%sbps/%sbps",
-                                           format_bytes_full(tx, sizeof tx, info->tx_bitrate, 0),
-                                           format_bytes_full(rx, sizeof rx, info->rx_bitrate, 0));
+                                           FORMAT_BYTES_FULL(info->tx_bitrate, 0),
+                                           FORMAT_BYTES_FULL(info->rx_bitrate, 0));
                 if (r < 0)
                         return table_log_add_error(r);
         }
@@ -2972,7 +2970,7 @@ static int parse_argv(int argc, char *argv[]) {
                         return -EINVAL;
 
                 default:
-                        assert_not_reached("Unhandled option");
+                        assert_not_reached();
                 }
         }
 
index 35305aff99f9c49412d15edca1d0299b88d1ebbe..c0d4e9ae673701a58f114182ebea8d488a36e14d 100644 (file)
@@ -16,6 +16,7 @@
 #include "parse-util.h"
 #include "string-util.h"
 #include "strv.h"
+#include "strxcpyx.h"
 
 #define ADDRESSES_PER_LINK_MAX 2048U
 #define STATIC_ADDRESSES_PER_NETWORK_MAX 1024U
@@ -165,7 +166,7 @@ Address *address_free(Address *address) {
                 set_remove(address->link->dhcp6_pd_addresses, address);
                 set_remove(address->link->dhcp6_pd_addresses_old, address);
                 SET_FOREACH(n, address->link->ndisc_addresses)
-                        if (n->address == address)
+                        if (address_equal(n->address, address))
                                 free(set_remove(address->link->ndisc_addresses, n));
 
                 if (address->family == AF_INET6 &&
@@ -620,11 +621,21 @@ int manager_has_address(Manager *manager, int family, const union in_addr_union
         return false;
 }
 
+const char* format_lifetime(char *buf, size_t l, uint32_t lifetime) {
+        assert(buf);
+        assert(l > 4);
+
+        if (lifetime == CACHE_INFO_INFINITY_LIFE_TIME)
+                return "forever";
+
+        sprintf(buf, "for ");
+        /* format_timespan() never fails */
+        assert_se(format_timespan(buf + 4, l - 4, lifetime * USEC_PER_SEC, USEC_PER_SEC));
+        return buf;
+}
+
 static void log_address_debug(const Address *address, const char *str, const Link *link) {
         _cleanup_free_ char *addr = NULL, *peer = NULL, *flags_str = NULL;
-        char valid_buf[FORMAT_TIMESPAN_MAX], preferred_buf[FORMAT_TIMESPAN_MAX];
-        const char *valid_str = NULL, *preferred_str = NULL;
-        bool has_peer;
 
         assert(address);
         assert(str);
@@ -634,27 +645,15 @@ static void log_address_debug(const Address *address, const char *str, const Lin
                 return;
 
         (void) in_addr_to_string(address->family, &address->in_addr, &addr);
-        has_peer = in_addr_is_set(address->family, &address->in_addr_peer);
-        if (has_peer)
+        if (in_addr_is_set(address->family, &address->in_addr_peer))
                 (void) in_addr_to_string(address->family, &address->in_addr_peer, &peer);
 
-        if (address->cinfo.ifa_valid != CACHE_INFO_INFINITY_LIFE_TIME)
-                valid_str = format_timespan(valid_buf, FORMAT_TIMESPAN_MAX,
-                                            address->cinfo.ifa_valid * USEC_PER_SEC,
-                                            USEC_PER_SEC);
-
-        if (address->cinfo.ifa_prefered != CACHE_INFO_INFINITY_LIFE_TIME)
-                preferred_str = format_timespan(preferred_buf, FORMAT_TIMESPAN_MAX,
-                                                address->cinfo.ifa_prefered * USEC_PER_SEC,
-                                                USEC_PER_SEC);
-
         (void) address_flags_to_string_alloc(address->flags, address->family, &flags_str);
 
-        log_link_debug(link, "%s address: %s%s%s/%u (valid %s%s, preferred %s%s), flags: %s",
-                       str, strnull(addr), has_peer ? " peer " : "",
-                       has_peer ? strnull(peer) : "", address->prefixlen,
-                       valid_str ? "for " : "forever", strempty(valid_str),
-                       preferred_str ? "for " : "forever", strempty(preferred_str),
+        log_link_debug(link, "%s address: %s%s%s/%u (valid %s, preferred %s), flags: %s",
+                       str, strnull(addr), peer ? " peer " : "", strempty(peer), address->prefixlen,
+                       FORMAT_LIFETIME(address->cinfo.ifa_valid),
+                       FORMAT_LIFETIME(address->cinfo.ifa_prefered),
                        strna(flags_str));
 }
 
@@ -1272,17 +1271,17 @@ int request_process_address(Request *req) {
         if (r <= 0)
                 return r;
 
-        r = address_get(link, req->address, &a);
-        if (r < 0)
-                return r;
-
-        r = address_configure(a, link, req->netlink_handler);
+        r = address_configure(req->address, link, req->netlink_handler);
         if (r < 0)
                 return r;
 
         /* To prevent a double decrement on failure in after_configure(). */
         req->message_counter = NULL;
 
+        r = address_get(link, req->address, &a);
+        if (r < 0)
+                return r;
+
         if (req->after_configure) {
                 r = req->after_configure(req, a);
                 if (r < 0)
@@ -1429,7 +1428,7 @@ int manager_rtnl_process_address(sd_netlink *rtnl, sd_netlink_message *message,
                 break;
 
         default:
-                assert_not_reached("Received unsupported address family");
+                assert_not_reached();
         }
 
         r = sd_netlink_message_read_cache_info(message, IFA_CACHEINFO, &tmp->cinfo);
@@ -1470,7 +1469,7 @@ int manager_rtnl_process_address(sd_netlink *rtnl, sd_netlink_message *message,
                 break;
 
         default:
-                assert_not_reached("Received invalid RTNL message type");
+                assert_not_reached();
         }
 
         return 1;
index ff3d46abdddad05aeb064343d2ec873a01479015..811940c12611f622091585adced0c77f3be78acb 100644 (file)
@@ -50,8 +50,15 @@ typedef struct Address {
         address_ready_callback_t callback;
 } Address;
 
+const char* format_lifetime(char *buf, size_t l, uint32_t lifetime) _warn_unused_result_;
+/* Note: the lifetime of the compound literal is the immediately surrounding block,
+ * see C11 §6.5.2.5, and
+ * https://stackoverflow.com/questions/34880638/compound-literal-lifetime-and-if-blocks */
+#define FORMAT_LIFETIME(lifetime) \
+        format_lifetime((char[FORMAT_TIMESPAN_MAX+STRLEN("for ")]){}, FORMAT_TIMESPAN_MAX+STRLEN("for "), lifetime)
+
 int address_new(Address **ret);
-Address *address_free(Address *address);
+Addressaddress_free(Address *address);
 int address_get(Link *link, const Address *in, Address **ret);
 int address_configure_handler_internal(sd_netlink *rtnl, sd_netlink_message *m, Link *link, const char *error_msg);
 int address_remove(const Address *address, Link *link);
index 0f808fb515dbcdbab009ce709e4578d935e6ec65..6eca4708265c980850f427594d155c2d60d8919b 100644 (file)
@@ -168,7 +168,7 @@ static int bridge_mdb_configure(BridgeMDB *mdb, Link *link, link_netlink_message
                 break;
 
         default:
-                assert_not_reached("Invalid address family");
+                assert_not_reached();
         }
 
         /* create new RTM message */
index 1fa37a058425c202583a632ed8a64546dbd55748..950b4134dd6b0129384f78cd40715bb7cbf996a5 100644 (file)
@@ -107,7 +107,6 @@ int can_set_netlink_message(Link *link, sd_netlink_message *m) {
         }
 
         if (link->network->can_restart_us > 0) {
-                char time_string[FORMAT_TIMESPAN_MAX];
                 uint64_t restart_ms;
 
                 if (link->network->can_restart_us == USEC_INFINITY)
@@ -115,12 +114,11 @@ int can_set_netlink_message(Link *link, sd_netlink_message *m) {
                 else
                         restart_ms = DIV_ROUND_UP(link->network->can_restart_us, USEC_PER_MSEC);
 
-                format_timespan(time_string, FORMAT_TIMESPAN_MAX, restart_ms * 1000, MSEC_PER_SEC);
-
                 if (restart_ms > UINT32_MAX)
-                        return log_link_debug_errno(link, SYNTHETIC_ERRNO(ERANGE), "restart timeout (%s) too big.", time_string);
+                        return log_link_debug_errno(link, SYNTHETIC_ERRNO(ERANGE), "restart timeout (%s) too big.",
+                                                    FORMAT_TIMESPAN(restart_ms * 1000, MSEC_PER_SEC));
 
-                log_link_debug(link, "Setting restart = %s", time_string);
+                log_link_debug(link, "Setting restart = %s", FORMAT_TIMESPAN(restart_ms * 1000, MSEC_PER_SEC));
 
                 r = sd_netlink_message_append_u32(m, IFLA_CAN_RESTART_MS, restart_ms);
                 if (r < 0)
index 0b55ef29a2581252d606fd8b88588b3ef8e72e30..9190dbfc53ae28f243597a5809036514bdd2c4b3 100644 (file)
@@ -29,10 +29,8 @@ int manager_parse_config_file(Manager *m) {
                 return r;
 
         if (m->use_speed_meter && m->speed_meter_interval_usec < SPEED_METER_MINIMUM_TIME_INTERVAL) {
-                char buf[FORMAT_TIMESPAN_MAX];
-
                 log_warning("SpeedMeterIntervalSec= is too small, using %s.",
-                            format_timespan(buf, sizeof buf, SPEED_METER_MINIMUM_TIME_INTERVAL, USEC_PER_SEC));
+                            FORMAT_TIMESPAN(SPEED_METER_MINIMUM_TIME_INTERVAL, USEC_PER_SEC));
                 m->speed_meter_interval_usec = SPEED_METER_MINIMUM_TIME_INTERVAL;
         }
 
index 9e2faa56753acd19fc52967847a21b85c1ce4731..e4be034a4c7c2f5bff805270567981e740219613 100644 (file)
@@ -202,7 +202,7 @@ static int link_push_uplink_to_dhcp_server(
                 break;
 
         default:
-                assert_not_reached("Unexpected server type");
+                assert_not_reached();
         }
 
         if (use_dhcp_lease_data && link->dhcp_lease) {
index f80adcdbcfef2289457906e07d22aadb692df3b6..c986031b87bce63ad4c9a3723ecf48a31fc6f02a 100644 (file)
@@ -5,7 +5,6 @@
 #include <linux/if.h>
 #include <linux/if_arp.h>
 
-#include "escape.h"
 #include "alloc-util.h"
 #include "dhcp-client-internal.h"
 #include "hostname-setup.h"
@@ -26,7 +25,6 @@
 #include "string-table.h"
 #include "strv.h"
 #include "sysctl-util.h"
-#include "web-util.h"
 
 static int dhcp4_request_address_and_routes(Link *link, bool announce);
 static int dhcp4_remove_all(Link *link);
@@ -381,9 +379,6 @@ static int dhcp4_request_static_routes(Link *link, struct in_addr *ret_default_g
         assert(link->dhcp_lease);
         assert(ret_default_gw);
 
-        if (!link->network->dhcp_use_routes)
-                return 0;
-
         n = sd_dhcp_lease_get_routes(link->dhcp_lease, &static_routes);
         if (IN_SET(n, 0, -ENODATA)) {
                 log_link_debug(link, "DHCP: No static routes received from DHCP server.");
@@ -408,6 +403,45 @@ static int dhcp4_request_static_routes(Link *link, struct in_addr *ret_default_g
         if (classless_route && static_route)
                 log_link_debug(link, "Classless static routes received from DHCP server: ignoring static-route option");
 
+        if (!link->network->dhcp_use_routes) {
+                if (!classless_route)
+                        return 0;
+
+                /* Even if UseRoutes=no, try to find default gateway to make semi-static routes and
+                 * routes to DNS or NTP servers can be configured in later steps. */
+                for (int i = 0; i < n; i++) {
+                        struct in_addr dst;
+                        uint8_t prefixlen;
+
+                        if (sd_dhcp_route_get_option(static_routes[i]) != SD_DHCP_OPTION_CLASSLESS_STATIC_ROUTE)
+                                continue;
+
+                        r = sd_dhcp_route_get_destination(static_routes[i], &dst);
+                        if (r < 0)
+                                return r;
+
+                        if (in4_addr_is_set(&dst))
+                                continue;
+
+                        r = sd_dhcp_route_get_destination_prefix_length(static_routes[i], &prefixlen);
+                        if (r < 0)
+                                return r;
+
+                        if (prefixlen != 0)
+                                continue;
+
+                        r = sd_dhcp_route_get_gateway(static_routes[i], ret_default_gw);
+                        if (r < 0)
+                                return r;
+
+                        break;
+                }
+
+                /* Do not return 1 here, to ensure the router option can override the default gateway
+                 * that was found. */
+                return 0;
+        }
+
         for (int i = 0; i < n; i++) {
                 _cleanup_(route_freep) Route *route = NULL;
                 struct in_addr gw;
@@ -456,19 +490,15 @@ static int dhcp4_request_static_routes(Link *link, struct in_addr *ret_default_g
         return classless_route;
 }
 
-static int dhcp4_request_gateway(Link *link, struct in_addr *ret_gw) {
+static int dhcp4_request_gateway(Link *link, struct in_addr *gw) {
         _cleanup_(route_freep) Route *route = NULL;
         const struct in_addr *router;
         struct in_addr address;
-        Route *rt;
         int r;
 
         assert(link);
         assert(link->dhcp_lease);
-        assert(ret_gw);
-
-        if (!link->network->dhcp_use_gateway)
-                return 0;
+        assert(gw);
 
         r = sd_dhcp_lease_get_address(link->dhcp_lease, &address);
         if (r < 0)
@@ -486,6 +516,16 @@ static int dhcp4_request_gateway(Link *link, struct in_addr *ret_gw) {
                 return 0;
         }
 
+        if (!link->network->dhcp_use_gateway) {
+                /* When no classless static route is provided, even if UseGateway=no, use the gateway
+                 * address to configure semi-static routes or routes to DNS or NTP servers. Note, if
+                 * neither UseRoutes= nor UseGateway= is disabled, use the default gateway in classless
+                 * static routes if provided (in that case, in4_addr_is_null(gw) below is true). */
+                if (in4_addr_is_null(gw))
+                        *gw = router[0];
+                return 0;
+        }
+
         /* The dhcp netmask may mask out the gateway. First, add an explicit route for the gateway host
          * so that we can route no matter the netmask or existing kernel route tables. */
         r = dhcp4_request_route_to_gateway(link, &router[0]);
@@ -510,18 +550,42 @@ static int dhcp4_request_gateway(Link *link, struct in_addr *ret_gw) {
         if (r < 0)
                 return r;
 
+        /* When no classless static route is provided, or UseRoutes=no, then use the router address to
+         * configure semi-static routes and routes to DNS or NTP servers in later steps. */
+        *gw = router[0];
+        return 0;
+}
+
+static int dhcp4_request_semi_static_routes(Link *link, const struct in_addr *gw) {
+        Route *rt;
+        int r;
+
+        assert(link);
+        assert(link->dhcp_lease);
+        assert(link->network);
+        assert(gw);
+
+        if (in4_addr_is_null(gw))
+                return 0;
+
         HASHMAP_FOREACH(rt, link->network->routes_by_section) {
+                _cleanup_(route_freep) Route *route = NULL;
+
                 if (!rt->gateway_from_dhcp_or_ra)
                         continue;
 
                 if (rt->gw_family != AF_INET)
                         continue;
 
+                r = dhcp4_request_route_to_gateway(link, gw);
+                if (r < 0)
+                        return r;
+
                 r = route_dup(rt, &route);
                 if (r < 0)
                         return r;
 
-                route->gw.in = router[0];
+                route->gw.in = *gw;
                 if (!route->protocol_set)
                         route->protocol = RTPROT_DHCP;
                 if (!route->priority_set)
@@ -536,7 +600,6 @@ static int dhcp4_request_gateway(Link *link, struct in_addr *ret_gw) {
                         return r;
         }
 
-        *ret_gw = router[0];
         return 0;
 }
 
@@ -655,6 +718,10 @@ static int dhcp4_request_routes(Link *link) {
                         return log_link_error_errno(link, r, "DHCP error: Could not request gateway: %m");
         }
 
+        r = dhcp4_request_semi_static_routes(link, &gw);
+        if (r < 0)
+                return log_link_error_errno(link, r, "DHCP error: Could not request routes with Gateway=_dhcp4 setting: %m");
+
         r = dhcp4_request_routes_to_dns(link, &gw);
         if (r < 0)
                 return log_link_error_errno(link, r, "DHCP error: Could not request routes to DNS servers: %m");
@@ -1322,7 +1389,7 @@ static int dhcp4_set_client_identifier(Link *link) {
                 break;
         }
         default:
-                assert_not_reached("Unknown client identifier type.");
+                assert_not_reached();
         }
 
         return 0;
@@ -1721,48 +1788,6 @@ int config_parse_dhcp_ip_service_type(
         return 0;
 }
 
-int config_parse_dhcp_mud_url(
-                const char *unit,
-                const char *filename,
-                unsigned line,
-                const char *section,
-                unsigned section_line,
-                const char *lvalue,
-                int ltype,
-                const char *rvalue,
-                void *data,
-                void *userdata) {
-
-        _cleanup_free_ char *unescaped = NULL;
-        Network *network = data;
-        int r;
-
-        assert(filename);
-        assert(lvalue);
-        assert(rvalue);
-
-        if (isempty(rvalue)) {
-                network->dhcp_mudurl = mfree(network->dhcp_mudurl);
-                return 0;
-        }
-
-        r = cunescape(rvalue, 0, &unescaped);
-        if (r < 0) {
-                log_syntax(unit, LOG_WARNING, filename, line, r,
-                           "Failed to Failed to unescape MUD URL, ignoring: %s", rvalue);
-                return 0;
-        }
-
-        if (!http_url_is_valid(unescaped) || strlen(unescaped) > 255) {
-                log_syntax(unit, LOG_WARNING, filename, line, 0,
-                           "Failed to parse MUD URL '%s', ignoring: %m", rvalue);
-
-                return 0;
-        }
-
-        return free_and_strdup_warn(&network->dhcp_mudurl, unescaped);
-}
-
 int config_parse_dhcp_fallback_lease_lifetime(const char *unit,
                 const char *filename,
                 unsigned line,
index 2b72b618fc5c2cb2886f288ee8e400825cb360bb..f03bf0651b182ac7e1f6b6be3f2a9e49b95dea50 100644 (file)
@@ -9,7 +9,6 @@
 
 #include "sd-dhcp6-client.h"
 
-#include "escape.h"
 #include "hashmap.h"
 #include "hostname-setup.h"
 #include "hostname-util.h"
@@ -24,7 +23,6 @@
 #include "string-table.h"
 #include "string-util.h"
 #include "radv-internal.h"
-#include "web-util.h"
 
 bool link_dhcp6_with_address_enabled(Link *link) {
         if (!link_dhcp6_enabled(link))
@@ -375,8 +373,6 @@ static int dhcp6_pd_address_handler(sd_netlink *rtnl, sd_netlink_message *m, Lin
 }
 
 static void log_dhcp6_pd_address(Link *link, const Address *address) {
-        char valid_buf[FORMAT_TIMESPAN_MAX], preferred_buf[FORMAT_TIMESPAN_MAX];
-        const char *valid_str = NULL, *preferred_str = NULL;
         _cleanup_free_ char *buffer = NULL;
         int log_level;
 
@@ -389,19 +385,11 @@ static void log_dhcp6_pd_address(Link *link, const Address *address) {
                 return;
 
         (void) in6_addr_prefix_to_string(&address->in_addr.in6, address->prefixlen, &buffer);
-        if (address->cinfo.ifa_valid != CACHE_INFO_INFINITY_LIFE_TIME)
-                valid_str = format_timespan(valid_buf, FORMAT_TIMESPAN_MAX,
-                                            address->cinfo.ifa_valid * USEC_PER_SEC,
-                                            USEC_PER_SEC);
-        if (address->cinfo.ifa_prefered != CACHE_INFO_INFINITY_LIFE_TIME)
-                preferred_str = format_timespan(preferred_buf, FORMAT_TIMESPAN_MAX,
-                                                address->cinfo.ifa_prefered * USEC_PER_SEC,
-                                                USEC_PER_SEC);
-
-        log_link_full(link, log_level, "DHCPv6-PD address %s (valid %s%s, preferred %s%s)",
+
+        log_link_full(link, log_level, "DHCPv6-PD address %s (valid %s, preferred %s)",
                       strna(buffer),
-                      valid_str ? "for " : "forever", strempty(valid_str),
-                      preferred_str ? "for " : "forever", strempty(preferred_str));
+                      FORMAT_LIFETIME(address->cinfo.ifa_valid),
+                      FORMAT_LIFETIME(address->cinfo.ifa_prefered));
 }
 
 static int dhcp6_pd_after_address_configure(Request *req, void *object) {
@@ -1063,8 +1051,6 @@ static int dhcp6_address_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *
 }
 
 static void log_dhcp6_address(Link *link, const Address *address, char **ret) {
-        char valid_buf[FORMAT_TIMESPAN_MAX], preferred_buf[FORMAT_TIMESPAN_MAX];
-        const char *valid_str = NULL, *preferred_str = NULL;
         _cleanup_free_ char *buffer = NULL;
         bool by_ndisc = false;
         Address *existing;
@@ -1076,14 +1062,6 @@ static void log_dhcp6_address(Link *link, const Address *address, char **ret) {
         assert(address->family == AF_INET6);
 
         (void) in6_addr_prefix_to_string(&address->in_addr.in6, address->prefixlen, &buffer);
-        if (address->cinfo.ifa_valid != CACHE_INFO_INFINITY_LIFE_TIME)
-                valid_str = format_timespan(valid_buf, FORMAT_TIMESPAN_MAX,
-                                            address->cinfo.ifa_valid * USEC_PER_SEC,
-                                            USEC_PER_SEC);
-        if (address->cinfo.ifa_prefered != CACHE_INFO_INFINITY_LIFE_TIME)
-                preferred_str = format_timespan(preferred_buf, FORMAT_TIMESPAN_MAX,
-                                                address->cinfo.ifa_prefered * USEC_PER_SEC,
-                                                USEC_PER_SEC);
 
         r = address_get(link, address, &existing);
         if (r < 0) {
@@ -1107,20 +1085,20 @@ static void log_dhcp6_address(Link *link, const Address *address, char **ret) {
                         break;
                 }
 
-        log_link_warning(link, "DHCPv6 address %s (valid %s%s, preferred %s%s) conflicts the existing address %s %s.",
+        log_link_warning(link, "DHCPv6 address %s (valid %s, preferred %s) conflicts the existing address %s %s.",
                          strna(buffer),
-                         valid_str ? "for " : "forever", strempty(valid_str),
-                         preferred_str ? "for " : "forever", strempty(preferred_str),
+                         FORMAT_LIFETIME(address->cinfo.ifa_valid),
+                         FORMAT_LIFETIME(address->cinfo.ifa_prefered),
                          strna(buffer),
                          by_ndisc ? "assigned by NDISC. Please try to use or update IPv6Token= setting "
                          "to change the address generated by NDISC, or disable UseAutonomousPrefix=" : "");
         goto finalize;
 
 simple_log:
-        log_link_full(link, log_level, "DHCPv6 address %s (valid %s%s, preferred %s%s)",
+        log_link_full(link, log_level, "DHCPv6 address %s (valid %s, preferred %s)",
                       strna(buffer),
-                      valid_str ? "for " : "forever", strempty(valid_str),
-                      preferred_str ? "for " : "forever", strempty(preferred_str));
+                      FORMAT_LIFETIME(address->cinfo.ifa_valid),
+                      FORMAT_LIFETIME(address->cinfo.ifa_prefered));
 
 finalize:
         if (ret)
@@ -1800,47 +1778,6 @@ int config_parse_dhcp6_pd_hint(
         return 0;
 }
 
-int config_parse_dhcp6_mud_url(
-                const char *unit,
-                const char *filename,
-                unsigned line,
-                const char *section,
-                unsigned section_line,
-                const char *lvalue,
-                int ltype,
-                const char *rvalue,
-                void *data,
-                void *userdata) {
-
-        _cleanup_free_ char *unescaped = NULL;
-        Network *network = data;
-        int r;
-
-        assert(filename);
-        assert(lvalue);
-        assert(rvalue);
-
-        if (isempty(rvalue)) {
-                network->dhcp6_mudurl = mfree(network->dhcp6_mudurl);
-                return 0;
-        }
-
-        r = cunescape(rvalue, 0, &unescaped);
-        if (r < 0) {
-                log_syntax(unit, LOG_WARNING, filename, line, r,
-                           "Failed to Failed to unescape MUD URL, ignoring: %s", rvalue);
-                return 0;
-        }
-
-        if (!http_url_is_valid(unescaped) || strlen(unescaped) > UINT8_MAX) {
-                log_syntax(unit, LOG_WARNING, filename, line, 0,
-                           "Failed to parse MUD URL '%s', ignoring: %m", rvalue);
-                return 0;
-        }
-
-        return free_and_replace(network->dhcp6_mudurl, unescaped);
-}
-
 DEFINE_CONFIG_PARSE_ENUM(config_parse_dhcp6_client_start_mode, dhcp6_client_start_mode, DHCP6ClientStartMode,
                          "Failed to parse WithoutRA= setting");
 
index c2cadc0a3028c79b54e733b0a51ddf3cff843b10..5c57032f2a851e4d7214504d45fb977e6e11195d 100644 (file)
@@ -117,7 +117,7 @@ static void on_acd(sd_ipv4acd *acd, int event, void *userdata, bool is_static) {
                 break;
 
         default:
-                assert_not_reached("Invalid IPv4ACD event.");
+                assert_not_reached();
         }
 }
 
index c1ab14ebec5d9d3747aa0e9b5a644b0cd76227e3..3a56f89f0b4b0fd87fdc667e085d06be1b040197 100644 (file)
@@ -1,9 +1,11 @@
 /* SPDX-License-Identifier: LGPL-2.1-or-later */
 
+#include <net/if.h>
 #include <netinet/in.h>
 #include <linux/if.h>
 #include <linux/if_arp.h>
 #include <linux/if_link.h>
+#include <linux/netdevice.h>
 #include <sys/socket.h>
 #include <unistd.h>
 
@@ -20,6 +22,7 @@
 #include "ethtool-util.h"
 #include "fd-util.h"
 #include "fileio.h"
+#include "format-util.h"
 #include "fs-util.h"
 #include "ipvlan.h"
 #include "missing_network.h"
@@ -2160,6 +2163,7 @@ static int link_update_alternative_names(Link *link, sd_netlink_message *message
 }
 
 static int link_update_name(Link *link, sd_netlink_message *message) {
+        char ifname_from_index[IF_NAMESIZE + 1];
         const char *ifname;
         int r;
 
@@ -2176,6 +2180,16 @@ static int link_update_name(Link *link, sd_netlink_message *message) {
         if (streq(ifname, link->ifname))
                 return 0;
 
+        if (!format_ifname(link->ifindex, ifname_from_index))
+                return log_link_debug_errno(link, SYNTHETIC_ERRNO(ENXIO), "Could not get interface name for index %i.", link->ifindex);
+
+        if (!streq(ifname, ifname_from_index)) {
+                log_link_debug(link, "New interface name '%s' received from the kernel does not correspond "
+                               "with the name currently configured on the actual interface '%s'. Ignoring.",
+                               ifname, ifname_from_index);
+                return 0;
+        }
+
         log_link_info(link, "Interface name change detected, renamed to %s.", ifname);
 
         hashmap_remove(link->manager->links_by_name, link->ifname);
@@ -2188,6 +2202,55 @@ static int link_update_name(Link *link, sd_netlink_message *message) {
         if (r < 0)
                 return log_link_debug_errno(link, r, "Failed to manage link by its new name: %m");
 
+        if (link->dhcp_client) {
+                r = sd_dhcp_client_set_ifname(link->dhcp_client, link->ifname);
+                if (r < 0)
+                        return log_link_debug_errno(link, r, "Failed to update interface name in DHCP client: %m");
+        }
+
+        if (link->dhcp6_client) {
+                r = sd_dhcp6_client_set_ifname(link->dhcp6_client, link->ifname);
+                if (r < 0)
+                        return log_link_debug_errno(link, r, "Failed to update interface name in DHCP6 client: %m");
+        }
+
+        if (link->ndisc) {
+                r = sd_ndisc_set_ifname(link->ndisc, link->ifname);
+                if (r < 0)
+                        return log_link_debug_errno(link, r, "Failed to update interface name in NDisc: %m");
+        }
+
+        if (link->dhcp_server) {
+                r = sd_dhcp_server_set_ifname(link->dhcp_server, link->ifname);
+                if (r < 0)
+                        return log_link_debug_errno(link, r, "Failed to update interface name in DHCP server: %m");
+        }
+
+        if (link->radv) {
+                r = sd_radv_set_ifname(link->radv, link->ifname);
+                if (r < 0)
+                        return log_link_debug_errno(link, r, "Failed to update interface name in Router Advertisement: %m");
+        }
+
+        if (link->lldp) {
+                r = sd_lldp_set_ifname(link->lldp, link->ifname);
+                if (r < 0)
+                        return log_link_debug_errno(link, r, "Failed to update interface name in LLDP: %m");
+        }
+
+        if (link->ipv4ll) {
+                r = sd_ipv4ll_set_ifname(link->ipv4ll, link->ifname);
+                if (r < 0)
+                        return log_link_debug_errno(link, r, "Failed to update interface name in IPv4LL client: %m");
+        }
+
+        Address *a;
+        SET_FOREACH(a, link->addresses_ipv4acd) {
+                r = sd_ipv4acd_set_ifname(a->acd, link->ifname);
+                if (r < 0)
+                        return log_link_debug_errno(link, r, "Failed to update interface name in IPv4ACD client: %m");
+        }
+
         return 0;
 }
 
@@ -2418,7 +2481,7 @@ int manager_rtnl_process_link(sd_netlink *rtnl, sd_netlink_message *message, Man
                 break;
 
         default:
-                assert_not_reached("Received link message with invalid RTNL message type.");
+                assert_not_reached();
         }
 
         return 1;
index 45a087b301c411eef317863ee1fbe858e2fb8b3a..061059558ec5bfec53b44c5311640b77043d535e 100644 (file)
@@ -7,7 +7,6 @@
 
 #include "alloc-util.h"
 #include "env-file.h"
-#include "escape.h"
 #include "fd-util.h"
 #include "hostname-util.h"
 #include "missing_network.h"
@@ -21,7 +20,6 @@
 #include "string-util.h"
 #include "strv.h"
 #include "unaligned.h"
-#include "web-util.h"
 
 /* The LLDP spec calls this "txFastInit", see 9.2.5.19 */
 #define LLDP_TX_FAST_INIT 4U
@@ -416,43 +414,6 @@ void link_lldp_emit_stop(Link *link) {
         link->lldp_emit_event_source = sd_event_source_unref(link->lldp_emit_event_source);
 }
 
-int config_parse_lldp_mud(
-                const char *unit,
-                const char *filename,
-                unsigned line,
-                const char *section,
-                unsigned section_line,
-                const char *lvalue,
-                int ltype,
-                const char *rvalue,
-                void *data,
-                void *userdata) {
-
-        _cleanup_free_ char *unescaped = NULL;
-        Network *n = data;
-        int r;
-
-        assert(filename);
-        assert(lvalue);
-        assert(rvalue);
-
-        r = cunescape(rvalue, 0, &unescaped);
-        if (r < 0) {
-                log_syntax(unit, LOG_WARNING, filename, line, r,
-                           "Failed to Failed to unescape LLDP MUD URL, ignoring: %s", rvalue);
-                return 0;
-        }
-
-        if (!http_url_is_valid(unescaped) || strlen(unescaped) > 255) {
-                log_syntax(unit, LOG_WARNING, filename, line, 0,
-                           "Failed to parse LLDP MUD URL '%s', ignoring: %m", rvalue);
-
-                return 0;
-        }
-
-        return free_and_replace(n->lldp_mud, unescaped);
-}
-
 static const char * const lldp_emit_table[_LLDP_EMIT_MAX] = {
         [LLDP_EMIT_NO]              = "no",
         [LLDP_EMIT_NEAREST_BRIDGE]  = "nearest-bridge",
index efc47078550847c7695012c261d30fd6b44a6521..96a3ef9cb82ea04f5c560068a80cd042360982f4 100644 (file)
@@ -1350,7 +1350,7 @@ static void ndisc_handler(sd_ndisc *nd, sd_ndisc_event_t event, sd_ndisc_router
                 }
                 break;
         default:
-                assert_not_reached("Unknown NDisc event");
+                assert_not_reached();
         }
 }
 
index b23f081bfb221ec1b06ddf44aeae08ad6c12114e..d5a8b6e97ee759a2e1e1c50ac6b8c8ad1a7c57d0 100644 (file)
@@ -595,7 +595,7 @@ int manager_rtnl_process_neighbor(sd_netlink *rtnl, sd_netlink_message *message,
                 break;
 
         default:
-                assert_not_reached("Received invalid RTNL message type");
+                assert_not_reached();
         }
 
         return 1;
index e3ced5a45c4b8f36ec6c71bd31fde139c9ba66db..de4120c47ec55db8518b0c5825475b153520861c 100644 (file)
@@ -214,7 +214,7 @@ DHCPv4.SendHostname,                         config_parse_bool,
 DHCPv4.Hostname,                             config_parse_hostname,                                    0,                             offsetof(Network, dhcp_hostname)
 DHCPv4.RequestBroadcast,                     config_parse_tristate,                                    0,                             offsetof(Network, dhcp_broadcast)
 DHCPv4.VendorClassIdentifier,                config_parse_string,                                      0,                             offsetof(Network, dhcp_vendor_class_identifier)
-DHCPv4.MUDURL,                               config_parse_dhcp_mud_url,                                0,                             0
+DHCPv4.MUDURL,                               config_parse_mud_url,                                     0,                             offsetof(Network, dhcp_mudurl)
 DHCPv4.MaxAttempts,                          config_parse_dhcp_max_attempts,                           0,                             0
 DHCPv4.UserClass,                            config_parse_dhcp_user_or_vendor_class,                   AF_INET,                       offsetof(Network, dhcp_user_class)
 DHCPv4.IAID,                                 config_parse_iaid,                                        AF_INET,                       0
@@ -239,7 +239,7 @@ DHCPv6.UseHostname,                          config_parse_bool,
 DHCPv6.UseDomains,                           config_parse_dhcp_use_domains,                            0,                             0
 DHCPv6.UseNTP,                               config_parse_dhcp_use_ntp,                                0,                             0
 DHCPv6.RapidCommit,                          config_parse_bool,                                        0,                             offsetof(Network, dhcp6_rapid_commit)
-DHCPv6.MUDURL,                               config_parse_dhcp6_mud_url,                               0,                             0
+DHCPv6.MUDURL,                               config_parse_mud_url,                                     0,                             offsetof(Network, dhcp6_mudurl)
 DHCPv6.RequestOptions,                       config_parse_dhcp_request_options,                        AF_INET6,                      0
 DHCPv6.UserClass,                            config_parse_dhcp_user_or_vendor_class,                   AF_INET6,                      offsetof(Network, dhcp6_user_class)
 DHCPv6.VendorClass,                          config_parse_dhcp_user_or_vendor_class,                   AF_INET6,                      offsetof(Network, dhcp6_vendor_class)
@@ -342,7 +342,7 @@ IPv6Prefix.Assign,                           config_parse_prefix_assign,
 IPv6Prefix.RouteMetric,                      config_parse_prefix_metric,                               0,                             0
 IPv6RoutePrefix.Route,                       config_parse_route_prefix,                                0,                             0
 IPv6RoutePrefix.LifetimeSec,                 config_parse_route_prefix_lifetime,                       0,                             0
-LLDP.MUDURL,                                 config_parse_lldp_mud,                                    0,                             0
+LLDP.MUDURL,                                 config_parse_mud_url,                                     0,                             offsetof(Network, lldp_mud)
 CAN.BitRate,                                 config_parse_can_bitrate,                                 0,                             offsetof(Network, can_bitrate)
 CAN.SamplePoint,                             config_parse_permille,                                    0,                             offsetof(Network, can_sample_point)
 CAN.DataBitRate,                             config_parse_can_bitrate,                                 0,                             offsetof(Network, can_data_bitrate)
index a52e5dcb16c8bb5c2a11d9920f3b40f5659eb080..92cbb1c843d2f2192aef2e9e0bcd52f4704bb145 100644 (file)
@@ -15,6 +15,7 @@
 #include "networkd-route.h"
 #include "parse-util.h"
 #include "set.h"
+#include "stdio-util.h"
 #include "string-util.h"
 
 NextHop *nexthop_free(NextHop *nexthop) {
@@ -368,7 +369,7 @@ set_manager:
 }
 
 static void log_nexthop_debug(const NextHop *nexthop, uint32_t id, const char *str, const Link *link) {
-        _cleanup_free_ char *gw = NULL, *new_id = NULL, *group = NULL;
+        _cleanup_free_ char *gw = NULL, *group = NULL;
         struct nexthop_grp *nhg;
 
         assert(nexthop);
@@ -379,8 +380,9 @@ static void log_nexthop_debug(const NextHop *nexthop, uint32_t id, const char *s
         if (!DEBUG_LOGGING)
                 return;
 
+        char new_id[STRLEN("→") + DECIMAL_STR_MAX(uint32_t)] = "";
         if (nexthop->id != id)
-                (void) asprintf(&new_id, "→%"PRIu32, id);
+                xsprintf(new_id, "→%"PRIu32, id);
 
         (void) in_addr_to_string(nexthop->family, &nexthop->gw, &gw);
 
@@ -388,7 +390,7 @@ static void log_nexthop_debug(const NextHop *nexthop, uint32_t id, const char *s
                 (void) strextendf_with_separator(&group, ",", "%"PRIu32":%"PRIu32, nhg->id, nhg->weight+1);
 
         log_link_debug(link, "%s nexthop: id: %"PRIu32"%s, gw: %s, blackhole: %s, group: %s",
-                       str, nexthop->id, strempty(new_id), strna(gw), yes_no(nexthop->blackhole), strna(group));
+                       str, nexthop->id, new_id, strna(gw), yes_no(nexthop->blackhole), strna(group));
 }
 
 static int link_nexthop_remove_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
@@ -1010,7 +1012,7 @@ int manager_rtnl_process_nexthop(sd_netlink *rtnl, sd_netlink_message *message,
                 break;
 
         default:
-                assert_not_reached("Received invalid RTNL message type");
+                assert_not_reached();
         }
 
         return 1;
@@ -1225,7 +1227,7 @@ int config_parse_nexthop_family(
                 n->family = AF_INET6;
                 break;
         default:
-                assert_not_reached("Invalid family.");
+                assert_not_reached();
         }
 
         TAKE_PTR(n);
index 5ef4acf5aca92a17940afad3aef4bcb324ecf470..db682d434b5bce0daf3d6db3746e6a1d66dc5fe4 100644 (file)
@@ -53,7 +53,7 @@ static void request_free_object(RequestType type, void *object) {
         case REQUEST_TYPE_UP_DOWN:
                 break;
         default:
-                assert_not_reached("invalid request type.");
+                assert_not_reached();
         }
 }
 
@@ -134,7 +134,7 @@ static void request_hash_func(const Request *req, struct siphash *state) {
         case REQUEST_TYPE_UP_DOWN:
                 break;
         default:
-                assert_not_reached("invalid request type.");
+                assert_not_reached();
         }
 }
 
@@ -181,7 +181,7 @@ static int request_compare_func(const struct Request *a, const struct Request *b
         case REQUEST_TYPE_UP_DOWN:
                 return 0;
         default:
-                assert_not_reached("invalid request type.");
+                assert_not_reached();
         }
 }
 
index 7b36b481419c89a890adbd31809d23fa7e4770d9..46fbf4f324c7cb25809231d11f3465b214c37d6f 100644 (file)
@@ -110,6 +110,7 @@ int manager_get_route_table_from_string(const Manager *m, const char *s, uint32_
 int manager_get_route_table_to_string(const Manager *m, uint32_t table, char **ret) {
         _cleanup_free_ char *str = NULL;
         const char *s;
+        int r;
 
         assert(m);
         assert(ret);
@@ -121,17 +122,13 @@ int manager_get_route_table_to_string(const Manager *m, uint32_t table, char **r
         if (!s)
                 s = hashmap_get(m->route_table_names_by_number, UINT32_TO_PTR(table));
 
-        if (s) {
+        if (s)
                 /* Currently, this is only used in debugging logs. To not confuse any bug
                  * reports, let's include the table number. */
-                if (asprintf(&str, "%s(%" PRIu32 ")", s, table) < 0)
-                        return -ENOMEM;
-
-                *ret = TAKE_PTR(str);
-                return 0;
-        }
-
-        if (asprintf(&str, "%" PRIu32, table) < 0)
+                r = asprintf(&str, "%s(%" PRIu32 ")", s, table);
+        else
+                r = asprintf(&str, "%" PRIu32, table);
+        if (r < 0)
                 return -ENOMEM;
 
         *ret = TAKE_PTR(str);
@@ -279,7 +276,7 @@ Route *route_free(Route *route) {
                 set_remove(route->link->dhcp6_pd_routes, route);
                 set_remove(route->link->dhcp6_pd_routes_old, route);
                 SET_FOREACH(n, route->link->ndisc_routes)
-                        if (n->route == route)
+                        if (route_equal(n->route, route))
                                 free(set_remove(route->link->ndisc_routes, n));
         }
 
@@ -435,7 +432,7 @@ DEFINE_HASH_OPS_WITH_KEY_DESTRUCTOR(
                 route_compare_func,
                 route_free);
 
-static bool route_equal(const Route *r1, const Route *r2) {
+bool route_equal(const Route *r1, const Route *r2) {
         if (r1 == r2)
                 return true;
 
@@ -746,6 +743,26 @@ static bool route_address_is_reachable(const Route *route, int family, const uni
                         FAMILY_ADDRESS_SIZE(family) * 8) > 0;
 }
 
+static bool prefix_route_address_is_reachable(const Address *a, int family, const union in_addr_union *address) {
+        assert(a);
+        assert(IN_SET(family, AF_INET, AF_INET6));
+        assert(address);
+
+        if (a->family != family)
+                return false;
+        if (FLAGS_SET(a->flags, IFA_F_NOPREFIXROUTE))
+                return false;
+        if (in_addr_is_set(a->family, &a->in_addr_peer))
+                return false;
+
+        return in_addr_prefix_intersect(
+                        family,
+                        &a->in_addr,
+                        a->prefixlen,
+                        address,
+                        FAMILY_ADDRESS_SIZE(family) * 8) > 0;
+}
+
 bool manager_address_is_reachable(Manager *manager, int family, const union in_addr_union *address) {
         Link *link;
 
@@ -764,6 +781,20 @@ bool manager_address_is_reachable(Manager *manager, int family, const union in_a
                                 return true;
         }
 
+        /* If we do not manage foreign routes, then there may exist a prefix route we do not know,
+         * which was created on configuring an address. Hence, also check the addresses. */
+        if (!manager->manage_foreign_routes)
+                HASHMAP_FOREACH(link, manager->links_by_index) {
+                        Address *a;
+
+                        SET_FOREACH(a, link->addresses)
+                                if (prefix_route_address_is_reachable(a, family, address))
+                                        return true;
+                        SET_FOREACH(a, link->addresses_foreign)
+                                if (prefix_route_address_is_reachable(a, family, address))
+                                        return true;
+                }
+
         return false;
 }
 
@@ -1850,7 +1881,7 @@ static int process_route_one(Manager *manager, Link *link, uint16_t type, const
                 break;
 
         default:
-                assert_not_reached("Received route message with invalid RTNL message type");
+                assert_not_reached();
         }
 
         return 1;
@@ -2304,7 +2335,7 @@ int config_parse_destination(
                 buffer = &n->src;
                 prefixlen = &n->src_prefixlen;
         } else
-                assert_not_reached(lvalue);
+                assert_not_reached();
 
         if (n->family == AF_UNSPEC)
                 r = in_addr_prefix_from_string_auto(rvalue, &n->family, buffer, prefixlen);
@@ -2549,7 +2580,7 @@ int config_parse_route_boolean(
         else if (streq(lvalue, "TTLPropagate"))
                 n->ttl_propagate = r;
         else
-                assert_not_reached("Invalid lvalue");
+                assert_not_reached();
 
         TAKE_PTR(n);
         return 0;
@@ -2783,7 +2814,7 @@ int config_parse_tcp_window(
         else if (streq(lvalue, "InitialAdvertisedReceiveWindow"))
                 n->initrwnd = k;
         else
-                assert_not_reached("Invalid TCP window type.");
+                assert_not_reached();
 
         TAKE_PTR(n);
         return 0;
index fa0b3ba0fc9213fc7e30f660ef853d77b6db522b..2d262819add0f3877d10aece97b1afbbd4dd369d 100644 (file)
@@ -66,6 +66,7 @@ typedef struct Route {
 
 void route_hash_func(const Route *route, struct siphash *state);
 int route_compare_func(const Route *a, const Route *b);
+bool route_equal(const Route *r1, const Route *r2);
 extern const struct hash_ops route_hash_ops;
 
 int route_new(Route **ret);
index af7e8a973cf47087be9e5b65f1af1a5acff40bb4..abf71a06a04858fbc4d541023d05f16196437bbb 100644 (file)
@@ -1051,7 +1051,7 @@ int manager_rtnl_process_rule(sd_netlink *rtnl, sd_netlink_message *message, Man
                 break;
 
         default:
-                assert_not_reached("Received invalid RTNL message type");
+                assert_not_reached();
         }
 
         return 1;
@@ -1636,7 +1636,7 @@ static int routing_policy_rule_section_verify(RoutingPolicyRule *rule) {
          * update routing_policy_rule_is_created_by_kernel() when a new setting which sets the flag is
          * added in the future. */
         if (rule->l3mdev > 0)
-                assert_not_reached("FRA_L3MDEV flag should not be configured.");
+                assert_not_reached();
 
         return 0;
 }
index a316a6c59b5aafe749d1d87d3a2b16168121c81f..8710518ebae65ab34a63ad0590954384ee0baf5e 100644 (file)
@@ -460,7 +460,7 @@ static int link_configure(
                         return log_link_debug_errno(link, r, "Could not append IFLA_MTU attribute: %m");
                 break;
         default:
-                assert_not_reached("Invalid set link operation");
+                assert_not_reached();
         }
 
         r = netlink_call_async(link->manager->rtnl, NULL, req, callback,
@@ -998,7 +998,7 @@ int link_request_to_activate(Link *link) {
                 up = false;
                 break;
         default:
-                assert_not_reached("invalid activation policy");
+                assert_not_reached();
         }
 
         link->activated = false;
index 7a76b61c4aefec0384bb1b92500564b0717eb4df..106560974e994e7ace4096a771ac3c9f246bc729 100644 (file)
@@ -309,7 +309,7 @@ int config_parse_sr_iov_uint32(
                 else if (streq(lvalue, "QualityOfService"))
                         sr_iov->qos = 0;
                 else
-                        assert_not_reached("Invalid lvalue");
+                        assert_not_reached();
 
                 TAKE_PTR(sr_iov);
                 return 0;
@@ -337,7 +337,7 @@ int config_parse_sr_iov_uint32(
         } else if (streq(lvalue, "QualityOfService"))
                 sr_iov->qos = k;
         else
-                assert_not_reached("Invalid lvalue");
+                assert_not_reached();
 
         TAKE_PTR(sr_iov);
         return 0;
@@ -467,7 +467,7 @@ int config_parse_sr_iov_boolean(
                 else if (streq(lvalue, "Trust"))
                         sr_iov->trust = -1;
                 else
-                        assert_not_reached("Invalid lvalue");
+                        assert_not_reached();
 
                 TAKE_PTR(sr_iov);
                 return 0;
@@ -486,7 +486,7 @@ int config_parse_sr_iov_boolean(
         else if (streq(lvalue, "Trust"))
                 sr_iov->trust = r;
         else
-                assert_not_reached("Invalid lvalue");
+                assert_not_reached();
 
         TAKE_PTR(sr_iov);
         return 0;
index 43ddf124d4457236a33bee8365a339823f0b8467..d7906e0cb5e9f487e4e02a4571c0d52b78f4c378 100644 (file)
@@ -2,12 +2,13 @@
 
 #include "condition.h"
 #include "conf-parser.h"
+#include "escape.h"
 #include "networkd-link.h"
 #include "networkd-util.h"
 #include "parse-util.h"
 #include "string-table.h"
 #include "string-util.h"
-#include "util.h"
+#include "web-util.h"
 
 static const char* const address_family_table[_ADDRESS_FAMILY_MAX] = {
         [ADDRESS_FAMILY_NO]   = "no",
@@ -161,6 +162,48 @@ int config_parse_ip_masquerade(
         return 0;
 }
 
+int config_parse_mud_url(
+                const char *unit,
+                const char *filename,
+                unsigned line,
+                const char *section,
+                unsigned section_line,
+                const char *lvalue,
+                int ltype,
+                const char *rvalue,
+                void *data,
+                void *userdata) {
+
+        _cleanup_free_ char *unescaped = NULL;
+        char **url = data;
+        ssize_t l;
+
+        assert(filename);
+        assert(lvalue);
+        assert(rvalue);
+        assert(url);
+
+        if (isempty(rvalue)) {
+                *url = mfree(*url);
+                return 0;
+        }
+
+        l = cunescape(rvalue, 0, &unescaped);
+        if (l < 0) {
+                log_syntax(unit, LOG_WARNING, filename, line, l,
+                           "Failed to unescape MUD URL, ignoring: %s", rvalue);
+                return 0;
+        }
+
+        if (l > UINT8_MAX || !http_url_is_valid(unescaped)) {
+                log_syntax(unit, LOG_WARNING, filename, line, 0,
+                           "Invalid MUD URL, ignoring: %s", rvalue);
+                return 0;
+        }
+
+        return free_and_replace(*url, unescaped);
+}
+
 /* Router lifetime can be set with netlink interface since kernel >= 4.5
  * so for the supported kernel we don't need to expire routes in userspace */
 int kernel_route_expiration_supported(void) {
index 62f38bcdc2c0b51d3409ce16ac7aee884edc7ac2..997bcee4b47771b0868fd0f6c52ca87b82eecd7f 100644 (file)
@@ -22,6 +22,7 @@ typedef struct NetworkConfigSection {
 CONFIG_PARSER_PROTOTYPE(config_parse_link_local_address_family);
 CONFIG_PARSER_PROTOTYPE(config_parse_address_family_with_kernel);
 CONFIG_PARSER_PROTOTYPE(config_parse_ip_masquerade);
+CONFIG_PARSER_PROTOTYPE(config_parse_mud_url);
 
 const char *address_family_to_string(AddressFamily b) _const_;
 AddressFamily address_family_from_string(const char *s) _pure_;
index 807c247b5747e38359dd0efb048a15e1d1303903..33f40d87d443da0350a0d3c944ac7385da310334 100644 (file)
@@ -168,7 +168,7 @@ int config_parse_controlled_delay_usec(
         else if (streq(lvalue, "CEThresholdSec"))
                 p = &cd->ce_threshold_usec;
         else
-                assert_not_reached("Invalid lvalue");
+                assert_not_reached();
 
         if (isempty(rvalue)) {
                 if (streq(lvalue, "CEThresholdSec"))
index 8214a575bf7b96d12644c9da1fd9d54bf62fd172..f8dd1adabc8e7079603e902b59a66580c31f22f5 100644 (file)
@@ -113,7 +113,7 @@ int config_parse_ets_u8(
         else if (streq(lvalue, "StrictBands"))
                 p = &ets->n_strict;
         else
-                assert_not_reached("Invalid lvalue.");
+                assert_not_reached();
 
         if (isempty(rvalue)) {
                 *p = 0;
index 3aa957373148eeda68cbf52ca5cf5d8c10e75ee1..3dd7f0b5f405e9e6edaee64c641727c505cc6576 100644 (file)
@@ -30,7 +30,7 @@ static int fifo_fill_message(Link *link, QDisc *qdisc, sd_netlink_message *req)
                 fifo = PFIFO_HEAD_DROP(qdisc);
                 break;
         default:
-                assert_not_reached("Invalid QDisc kind.");
+                assert_not_reached();
         }
 
         opt.limit = fifo->limit;
@@ -81,7 +81,7 @@ int config_parse_pfifo_size(
                 fifo = PFIFO_HEAD_DROP(qdisc);
                 break;
         default:
-                assert_not_reached("Invalid QDisc kind.");
+                assert_not_reached();
         }
 
         if (isempty(rvalue)) {
index bcc734df90fc910a9e3ce2a3ebbe9264e7e1f732..7c61cf2ac65e4e896fce40da3680b757fa805efb 100644 (file)
@@ -133,7 +133,7 @@ int config_parse_fair_queueing_controlled_delay_u32(
         else if (streq(lvalue, "Flows"))
                 p = &fqcd->flows;
         else
-                assert_not_reached("Invalid lvalue.");
+                assert_not_reached();
 
         if (isempty(rvalue)) {
                 *p = 0;
@@ -196,7 +196,7 @@ int config_parse_fair_queueing_controlled_delay_usec(
         else if (streq(lvalue, "CEThresholdSec"))
                 p = &fqcd->ce_threshold_usec;
         else
-                assert_not_reached("Invalid lvalue.");
+                assert_not_reached();
 
         if (isempty(rvalue)) {
                 if (streq(lvalue, "CEThresholdSec"))
@@ -315,7 +315,7 @@ int config_parse_fair_queueing_controlled_delay_size(
         else if (STR_IN_SET(lvalue, "QuantumBytes", "Quantum"))
                 p = &fqcd->quantum;
         else
-                assert_not_reached("Invalid lvalue.");
+                assert_not_reached();
 
         if (isempty(rvalue)) {
                 if (STR_IN_SET(lvalue, "MemoryLimitBytes", "MemoryLimit"))
index d48aea86fbca05885f54cb242b6bb74c58f24bc4..d10a863495cc88153a51e3657c9d93a0eeb7d4c9 100644 (file)
@@ -145,7 +145,7 @@ int config_parse_fair_queueing_u32(
         else if (streq(lvalue, "OrphanMask"))
                 p = &fq->orphan_mask;
         else
-                assert_not_reached("Invalid lvalue");
+                assert_not_reached();
 
         if (isempty(rvalue)) {
                 *p = 0;
@@ -207,7 +207,7 @@ int config_parse_fair_queueing_size(
         else if (STR_IN_SET(lvalue, "InitialQuantumBytes", "InitialQuantum"))
                 p = &fq->initial_quantum;
         else
-                assert_not_reached("Invalid lvalue");
+                assert_not_reached();
 
         if (isempty(rvalue)) {
                 *p = 0;
index 04fcd59e48bcfa262e3008d55d3cfaef2a8518d3..ce26e62450fae3ceec56deddbfea1bd6af052d96 100644 (file)
@@ -106,7 +106,7 @@ int config_parse_generic_random_early_detection_u32(
         else if (streq(lvalue, "DefaultVirtualQueue"))
                 p = &gred->default_virtual_queue;
         else
-                assert_not_reached("Invalid lvalue.");
+                assert_not_reached();
 
         if (isempty(rvalue)) {
                 *p = 0;
index 17455248a7a66af31c23c5e6237ee43a7392c1f7..14fb1f92e34fac50658a76a36514040a28353d39 100644 (file)
@@ -338,7 +338,7 @@ int config_parse_hierarchy_token_bucket_class_size(
                 else if (streq(lvalue, "CeilBufferBytes"))
                         htb->ceil_buffer = 0;
                 else
-                        assert_not_reached("Invalid lvalue");
+                        assert_not_reached();
 
                 tclass = NULL;
                 return 0;
@@ -369,7 +369,7 @@ int config_parse_hierarchy_token_bucket_class_size(
         else if (streq(lvalue, "CeilBufferBytes"))
                 htb->ceil_buffer = v;
         else
-                assert_not_reached("Invalid lvalue");
+                assert_not_reached();
 
         tclass = NULL;
 
@@ -414,7 +414,7 @@ int config_parse_hierarchy_token_bucket_class_rate(
         else if (streq(lvalue, "CeilRate"))
                 v = &htb->ceil_rate;
         else
-                assert_not_reached("Invalid lvalue");
+                assert_not_reached();
 
         if (isempty(rvalue)) {
                 *v = 0;
index 50d14a535646d2e3f3fb19f9fd735717f7d7ce43..1d1bc6f0e90a74efdc4162191ed8c6f88c36226a 100644 (file)
@@ -154,7 +154,7 @@ int config_parse_token_bucket_filter_size(
                 else if (streq(lvalue, "MPUBytes"))
                         tbf->mpu = 0;
                 else
-                        assert_not_reached("unknown lvalue");
+                        assert_not_reached();
 
                 TAKE_PTR(qdisc);
                 return 0;
@@ -177,7 +177,7 @@ int config_parse_token_bucket_filter_size(
         else if (streq(lvalue, "MTUBytes"))
                 tbf->mtu = k;
         else
-                assert_not_reached("unknown lvalue");
+                assert_not_reached();
 
         TAKE_PTR(qdisc);
 
@@ -222,7 +222,7 @@ int config_parse_token_bucket_filter_rate(
         else if (streq(lvalue, "PeakRate"))
                 p = &tbf->peak_rate;
         else
-                assert_not_reached("unknown lvalue");
+                assert_not_reached();
 
         if (isempty(rvalue)) {
                 *p = 0;
index 0cd46cf6339fffa01334d49ce230c221679409e7..a3cfed53fa22857ab57f5004a43297b8bad26aab 100644 (file)
@@ -17,7 +17,7 @@ void traffic_control_free(TrafficControl *tc) {
                 tclass_free(TC_TO_TCLASS(tc));
                 break;
         default:
-                assert_not_reached("Invalid traffic control type");
+                assert_not_reached();
         }
 }
 
@@ -31,7 +31,7 @@ static int traffic_control_configure(Link *link, TrafficControl *tc) {
         case TC_KIND_TCLASS:
                 return tclass_configure(link, TC_TO_TCLASS(tc));
         default:
-                assert_not_reached("Invalid traffic control type");
+                assert_not_reached();
         }
 }
 
@@ -72,7 +72,7 @@ static int traffic_control_section_verify(TrafficControl *tc, bool *qdisc_has_ro
         case TC_KIND_TCLASS:
                 return tclass_section_verify(TC_TO_TCLASS(tc));
         default:
-                assert_not_reached("Invalid traffic control type");
+                assert_not_reached();
         }
 }
 
diff --git a/src/network/test-networkd-address.c b/src/network/test-networkd-address.c
new file mode 100644 (file)
index 0000000..7c1d65a
--- /dev/null
@@ -0,0 +1,28 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+
+#include "networkd-address.h"
+#include "tests.h"
+
+static void test_FORMAT_LIFETIME_one(uint32_t lifetime, const char *expected) {
+        const char *t = FORMAT_LIFETIME(lifetime);
+
+        log_debug("%"PRIu32 " → \"%s\" (expected \"%s\")", lifetime, t, expected);
+        assert_se(streq(t, expected));
+}
+
+static void test_FORMAT_LIFETIME(void) {
+        log_info("/* %s */", __func__);
+
+        test_FORMAT_LIFETIME_one(0, "for 0");
+        test_FORMAT_LIFETIME_one(1, "for 1s");
+        test_FORMAT_LIFETIME_one(3 * (USEC_PER_WEEK/USEC_PER_SEC), "for 3w");
+        test_FORMAT_LIFETIME_one(CACHE_INFO_INFINITY_LIFE_TIME, "forever");
+}
+
+int main(int argc, char *argv[]) {
+        test_setup_logging(LOG_INFO);
+
+        test_FORMAT_LIFETIME();
+
+        return 0;
+}
index 1b24b6f1a695dad0e78cf48ea4b1c9e3a9d534e8..ad6f18bbd4c34bffca378539279c164ef23f6af8 100644 (file)
@@ -187,7 +187,7 @@ static int parse_argv(int argc, char *argv[]) {
                         return -EINVAL;
 
                 default:
-                        assert_not_reached("Unhandled option");
+                        assert_not_reached();
                 }
 
         return 1;
index 99f54ceaaab609d8c3b1bd0f24c88c4d91af2e96..49d5f3ec92a581d27719665455ee1bf2e7ad002c 100644 (file)
@@ -170,7 +170,7 @@ static int parse_argv(int argc, char *argv[]) {
                         return -EINVAL;
 
                 default:
-                        assert_not_reached("Unhandled option");
+                        assert_not_reached();
                 }
         }
 
index 6852125b9d33dc31e23589cf99414b5df33bb798..3250cd9768fb698e75cecb2d55ef795067f17deb 100644 (file)
@@ -171,10 +171,8 @@ static int find_free_uid(const char *directory, uid_t max_uid, uid_t *current_ui
 
                 /* We want to use the UID also as GID, hence check for it in /etc/group too */
                 r = check_etc_group_collisions(directory, NULL, (gid_t) *current_uid);
-                if (r < 0)
+                if (r <= 0)
                         return r;
-                if (r == 0) /* free! yay! */
-                        return 0;
         }
 }
 
index 60f956da0f612a8b88d80b8716e981f42fb313fe..c59151685c97545ecf3db7bee71f4e677dec5ef0 100644 (file)
@@ -946,7 +946,7 @@ int mount_custom(
                         break;
 
                 default:
-                        assert_not_reached("Unknown custom mount type");
+                        assert_not_reached();
                 }
 
                 if (r < 0)
index 3cbe4ef5a6c1a3717ed21836dde57f241a51f777..6dbd6ba4c9e45983346ee5fdec46e3a2336eb62d 100644 (file)
@@ -180,7 +180,7 @@ int stub_pid1(sd_id128_t uuid) {
 
                         state = STATE_REBOOT;
                 else
-                        assert_not_reached("Got unexpected signal");
+                        assert_not_reached();
 
                 r = kill_and_sigcont(pid, SIGTERM);
 
index 04685fecbaf35d0e81fdb7cb412cf59c0bd9d3b5..d75cce408e742d2e5f193352ca252a2ba33a270d 100644 (file)
@@ -1564,8 +1564,7 @@ static int parse_argv(int argc, char *argv[]) {
                         _cleanup_free_ char *word = NULL, *data = NULL;
                         const char *p = optarg;
                         Credential *a;
-                        size_t i;
-                        int l;
+                        ssize_t l;
 
                         r = extract_first_word(&p, &word, ":", EXTRACT_DONT_COALESCE_SEPARATORS);
                         if (r == -ENOMEM)
@@ -1578,7 +1577,7 @@ static int parse_argv(int argc, char *argv[]) {
                         if (!credential_name_valid(word))
                                 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Credential name is not valid: %s", word);
 
-                        for (i = 0; i < arg_n_credentials; i++)
+                        for (size_t i = 0; i < arg_n_credentials; i++)
                                 if (streq(arg_credentials[i].id, word))
                                         return log_error_errno(SYNTHETIC_ERRNO(EEXIST), "Duplicate credential '%s', refusing.", word);
 
@@ -1676,7 +1675,7 @@ static int parse_argv(int argc, char *argv[]) {
                         return -EINVAL;
 
                 default:
-                        assert_not_reached("Unhandled option");
+                        assert_not_reached();
                 }
 
         if (argc > optind) {
@@ -2014,7 +2013,7 @@ static int setup_timezone(const char *dest) {
                 break;
 
         default:
-                assert_not_reached("unexpected mode");
+                assert_not_reached();
         }
 
         /* Fix permissions of the symlink or file copy we just created */
@@ -4091,7 +4090,7 @@ static int make_uid_map_string(
         int r;
 
         assert(n_bind_user_uid == 0 || bind_user_uid);
-        assert(offset == 0 || offset == 2); /* used to switch between UID and GID map */
+        assert(IN_SET(offset, 0, 2)); /* used to switch between UID and GID map */
         assert(ret);
 
         /* The bind_user_uid[] array is a series of 4 uid_t values, for each --bind-user= entry one
index 0d215cf6e977c083670e8fc2fb32da9145368bc9..1836dc1014fef990b687d50a4d45ea566c498fc2 100644 (file)
@@ -110,7 +110,7 @@ static int parse_argv(int argc, char *argv[]) {
                                 return -EINVAL;
 
                         default:
-                                assert_not_reached("Invalid option passed.");
+                                assert_not_reached();
                 }
 
         return 1;
index 9cae0c9c8af36a00c0da6ed9e7851de3e02dbee9..4d7c28fe8ec1efd1852fe8668e6b69b60ced6c35 100644 (file)
@@ -442,7 +442,6 @@ static int monitor_memory_pressure_contexts_handler(sd_event_source *s, uint64_t
                 OomdCGroupContext *t;
                 SET_FOREACH(t, targets) {
                         _cleanup_free_ char *selected = NULL;
-                        char ts[FORMAT_TIMESPAN_MAX];
 
                         /* Check if there was reclaim activity in the given interval. The concern is the following case:
                          * Pressure climbed, a lot of high-frequency pages were reclaimed, and we killed the offending
@@ -456,9 +455,7 @@ static int monitor_memory_pressure_contexts_handler(sd_event_source *s, uint64_t
                                   t->path,
                                   LOAD_INT(t->memory_pressure.avg10), LOAD_FRAC(t->memory_pressure.avg10),
                                   LOAD_INT(t->mem_pressure_limit), LOAD_FRAC(t->mem_pressure_limit),
-                                  format_timespan(ts, sizeof ts,
-                                                  m->default_mem_pressure_duration_usec,
-                                                  USEC_PER_SEC));
+                                  FORMAT_TIMESPAN(m->default_mem_pressure_duration_usec, USEC_PER_SEC));
 
                         r = update_monitored_cgroup_contexts_candidates(
                                         m->monitored_mem_pressure_cgroup_contexts, &m->monitored_mem_pressure_cgroup_contexts_candidates);
@@ -483,9 +480,7 @@ static int monitor_memory_pressure_contexts_handler(sd_event_source *s, uint64_t
                                                    selected, t->path,
                                                    LOAD_INT(t->memory_pressure.avg10), LOAD_FRAC(t->memory_pressure.avg10),
                                                    LOAD_INT(t->mem_pressure_limit), LOAD_FRAC(t->mem_pressure_limit),
-                                                   format_timespan(ts, sizeof ts,
-                                                                   m->default_mem_pressure_duration_usec,
-                                                                   USEC_PER_SEC));
+                                                   FORMAT_TIMESPAN(m->default_mem_pressure_duration_usec, USEC_PER_SEC));
                                 return 0;
                         }
                 }
@@ -707,7 +702,6 @@ int manager_start(
 int manager_get_dump_string(Manager *m, char **ret) {
         _cleanup_free_ char *dump = NULL;
         _cleanup_fclose_ FILE *f = NULL;
-        char buf[FORMAT_TIMESPAN_MAX];
         OomdCGroupContext *c;
         size_t size;
         char *key;
@@ -729,7 +723,7 @@ int manager_get_dump_string(Manager *m, char **ret) {
                 yes_no(m->dry_run),
                 PERMYRIAD_AS_PERCENT_FORMAT_VAL(m->swap_used_limit_permyriad),
                 LOAD_INT(m->default_mem_pressure_limit), LOAD_FRAC(m->default_mem_pressure_limit),
-                format_timespan(buf, sizeof(buf), m->default_mem_pressure_duration_usec, USEC_PER_SEC));
+                FORMAT_TIMESPAN(m->default_mem_pressure_duration_usec, USEC_PER_SEC));
         oomd_dump_system_context(&m->system_context, f, "\t");
 
         fprintf(f, "Swap Monitored CGroups:\n");
index b2a48acb1f469c07053dfe38443167f018b0e283..ff0fc13c6faeec09db3a6bbfcde80e46d6f8bbd2 100644 (file)
@@ -503,8 +503,6 @@ void oomd_update_cgroup_contexts_between_hashmaps(Hashmap *old_h, Hashmap *curr_
 }
 
 void oomd_dump_swap_cgroup_context(const OomdCGroupContext *ctx, FILE *f, const char *prefix) {
-        char swap[FORMAT_BYTES_MAX];
-
         assert(ctx);
         assert(f);
 
@@ -513,7 +511,7 @@ void oomd_dump_swap_cgroup_context(const OomdCGroupContext *ctx, FILE *f, const
                         "%sPath: %s\n"
                         "%s\tSwap Usage: %s\n",
                         strempty(prefix), ctx->path,
-                        strempty(prefix), format_bytes(swap, sizeof(swap), ctx->swap_usage));
+                        strempty(prefix), FORMAT_BYTES(ctx->swap_usage));
         else
                 fprintf(f,
                         "%sPath: %s\n"
@@ -523,9 +521,6 @@ void oomd_dump_swap_cgroup_context(const OomdCGroupContext *ctx, FILE *f, const
 }
 
 void oomd_dump_memory_pressure_cgroup_context(const OomdCGroupContext *ctx, FILE *f, const char *prefix) {
-        char tbuf[FORMAT_TIMESPAN_MAX], mem_use[FORMAT_BYTES_MAX];
-        char mem_min[FORMAT_BYTES_MAX], mem_low[FORMAT_BYTES_MAX];
-
         assert(ctx);
         assert(f);
 
@@ -540,8 +535,8 @@ void oomd_dump_memory_pressure_cgroup_context(const OomdCGroupContext *ctx, FILE
                 LOAD_INT(ctx->memory_pressure.avg10), LOAD_FRAC(ctx->memory_pressure.avg10),
                 LOAD_INT(ctx->memory_pressure.avg60), LOAD_FRAC(ctx->memory_pressure.avg60),
                 LOAD_INT(ctx->memory_pressure.avg300), LOAD_FRAC(ctx->memory_pressure.avg300),
-                format_timespan(tbuf, sizeof(tbuf), ctx->memory_pressure.total, USEC_PER_SEC),
-                strempty(prefix), format_bytes(mem_use, sizeof(mem_use), ctx->current_memory_usage));
+                FORMAT_TIMESPAN(ctx->memory_pressure.total, USEC_PER_SEC),
+                strempty(prefix), FORMAT_BYTES(ctx->current_memory_usage));
 
         if (!empty_or_root(ctx->path))
                 fprintf(f,
@@ -549,16 +544,13 @@ void oomd_dump_memory_pressure_cgroup_context(const OomdCGroupContext *ctx, FILE
                         "%s\tMemory Low: %s\n"
                         "%s\tPgscan: %" PRIu64 "\n"
                         "%s\tLast Pgscan: %" PRIu64 "\n",
-                        strempty(prefix), format_bytes_cgroup_protection(mem_min, sizeof(mem_min), ctx->memory_min),
-                        strempty(prefix), format_bytes_cgroup_protection(mem_low, sizeof(mem_low), ctx->memory_low),
+                        strempty(prefix), FORMAT_BYTES_CGROUP_PROTECTION(ctx->memory_min),
+                        strempty(prefix), FORMAT_BYTES_CGROUP_PROTECTION(ctx->memory_low),
                         strempty(prefix), ctx->pgscan,
                         strempty(prefix), ctx->last_pgscan);
 }
 
 void oomd_dump_system_context(const OomdSystemContext *ctx, FILE *f, const char *prefix) {
-        char mem_used[FORMAT_BYTES_MAX], mem_total[FORMAT_BYTES_MAX];
-        char swap_used[FORMAT_BYTES_MAX], swap_total[FORMAT_BYTES_MAX];
-
         assert(ctx);
         assert(f);
 
@@ -566,9 +558,9 @@ void oomd_dump_system_context(const OomdSystemContext *ctx, FILE *f, const char
                 "%sMemory: Used: %s Total: %s\n"
                 "%sSwap: Used: %s Total: %s\n",
                 strempty(prefix),
-                format_bytes(mem_used, sizeof(mem_used), ctx->mem_used),
-                format_bytes(mem_total, sizeof(mem_total), ctx->mem_total),
+                FORMAT_BYTES(ctx->mem_used),
+                FORMAT_BYTES(ctx->mem_total),
                 strempty(prefix),
-                format_bytes(swap_used, sizeof(swap_used), ctx->swap_used),
-                format_bytes(swap_total, sizeof(swap_total), ctx->swap_total));
+                FORMAT_BYTES(ctx->swap_used),
+                FORMAT_BYTES(ctx->swap_total));
 }
index deb7b094d504b49858f78f57a1ff9bf5361ac859..8d4014ee0633d73a69ce3e394870b2b79fbd8ade 100644 (file)
@@ -105,7 +105,7 @@ static int parse_argv(int argc, char *argv[]) {
                         return -EINVAL;
 
                 default:
-                        assert_not_reached("Unknown option code.");
+                        assert_not_reached();
                 }
 
         if (optind < argc)
index 15c56d058437d7c33ac19c9a3f2e60857b4274b1..af6a9ef600dad988c2a1834f01e2f287374f2381 100644 (file)
@@ -180,7 +180,7 @@ static int parse_argv(int argc, char *argv[]) {
                         return -EINVAL;
 
                 default:
-                        assert_not_reached("Unhandled option");
+                        assert_not_reached();
                 }
 
         if (optind + 1 != argc)
@@ -197,7 +197,6 @@ static int run(int argc, char *argv[]) {
         _cleanup_close_ int mountfd = -1, devfd = -1;
         _cleanup_free_ char *devpath = NULL;
         uint64_t size, newsize;
-        char fb[FORMAT_BYTES_MAX];
         dev_t devno;
         int r;
 
@@ -248,11 +247,11 @@ static int run(int argc, char *argv[]) {
         if (newsize == size)
                 log_info("Successfully resized \"%s\" to %s bytes.",
                          arg_target,
-                         format_bytes(fb, sizeof fb, newsize));
+                         FORMAT_BYTES(newsize));
         else
                 log_info("Successfully resized \"%s\" to %s bytes (%"PRIu64" bytes lost due to blocksize).",
                          arg_target,
-                         format_bytes(fb, sizeof fb, newsize),
+                         FORMAT_BYTES(newsize),
                          size - newsize);
         return 0;
 }
index ac317f6adca3a0c809401fa7e24e78b61e45f6f1..c75198e5c97b142b61c852c8459975ddbea26951 100644 (file)
@@ -1932,29 +1932,24 @@ static void context_unload_partition_table(Context *context) {
 }
 
 static int format_size_change(uint64_t from, uint64_t to, char **ret) {
-        char format_buffer1[FORMAT_BYTES_MAX], format_buffer2[FORMAT_BYTES_MAX], *buf;
-
-        if (from != UINT64_MAX)
-                format_bytes(format_buffer1, sizeof(format_buffer1), from);
-        if (to != UINT64_MAX)
-                format_bytes(format_buffer2, sizeof(format_buffer2), to);
+        char *t;
 
         if (from != UINT64_MAX) {
                 if (from == to || to == UINT64_MAX)
-                        buf = strdup(format_buffer1);
+                        t = strdup(FORMAT_BYTES(from));
                 else
-                        buf = strjoin(format_buffer1, " ", special_glyph(SPECIAL_GLYPH_ARROW), " ", format_buffer2);
+                        t = strjoin(FORMAT_BYTES(from), " ", special_glyph(SPECIAL_GLYPH_ARROW), " ", FORMAT_BYTES(to));
         } else if (to != UINT64_MAX)
-                buf = strjoin(special_glyph(SPECIAL_GLYPH_ARROW), " ", format_buffer2);
+                t = strjoin(special_glyph(SPECIAL_GLYPH_ARROW), " ", FORMAT_BYTES(to));
         else {
                 *ret = NULL;
                 return 0;
         }
 
-        if (!buf)
+        if (!t)
                 return log_oom();
 
-        *ret = TAKE_PTR(buf);
+        *ret = t;
         return 1;
 }
 
@@ -2051,11 +2046,10 @@ static int context_dump_partitions(Context *context, const char *node) {
         }
 
         if ((arg_json_format_flags & JSON_FORMAT_OFF) && (sum_padding > 0 || sum_size > 0)) {
-                char s[FORMAT_BYTES_MAX];
                 const char *a, *b;
 
-                a = strjoina(special_glyph(SPECIAL_GLYPH_SIGMA), " = ", format_bytes(s, sizeof(s), sum_size));
-                b = strjoina(special_glyph(SPECIAL_GLYPH_SIGMA), " = ", format_bytes(s, sizeof(s), sum_padding));
+                a = strjoina(special_glyph(SPECIAL_GLYPH_SIGMA), " = ", FORMAT_BYTES(sum_size));
+                b = strjoina(special_glyph(SPECIAL_GLYPH_SIGMA), " = ", FORMAT_BYTES(sum_padding));
 
                 r = table_add_many(
                                 t,
@@ -2630,9 +2624,10 @@ static int partition_encrypt(
                 _cleanup_(erase_and_freep) void *secret = NULL;
                 _cleanup_free_ void *blob = NULL, *hash = NULL;
                 size_t secret_size, blob_size, hash_size;
+                uint16_t pcr_bank;
                 int keyslot;
 
-                r = tpm2_seal(arg_tpm2_device, arg_tpm2_pcr_mask, &secret, &secret_size, &blob, &blob_size, &hash, &hash_size);
+                r = tpm2_seal(arg_tpm2_device, arg_tpm2_pcr_mask, &secret, &secret_size, &blob, &blob_size, &hash, &hash_size, &pcr_bank);
                 if (r < 0)
                         return log_error_errno(r, "Failed to seal to TPM2: %m");
 
@@ -2654,7 +2649,7 @@ static int partition_encrypt(
                 if (keyslot < 0)
                         return log_error_errno(keyslot, "Failed to add new TPM2 key to %s: %m", node);
 
-                r = tpm2_make_luks2_json(keyslot, arg_tpm2_pcr_mask, blob, blob_size, hash, hash_size, &v);
+                r = tpm2_make_luks2_json(keyslot, arg_tpm2_pcr_mask, pcr_bank, blob, blob_size, hash, hash_size, &v);
                 if (r < 0)
                         return log_error_errno(r, "Failed to prepare TPM2 JSON token object: %m");
 
@@ -2734,7 +2729,6 @@ static int context_copy_blocks(Context *context) {
                 _cleanup_(loop_device_unrefp) LoopDevice *d = NULL;
                 _cleanup_free_ char *encrypted = NULL;
                 _cleanup_close_ int encrypted_dev_fd = -1;
-                char buf[FORMAT_BYTES_MAX];
                 int target_fd;
 
                 if (p->copy_blocks_fd < 0)
@@ -2777,7 +2771,8 @@ static int context_copy_blocks(Context *context) {
                         target_fd = whole_fd;
                 }
 
-                log_info("Copying in '%s' (%s) on block level into future partition %" PRIu64 ".", p->copy_blocks_path, format_bytes(buf, sizeof(buf), p->copy_blocks_size), p->partno);
+                log_info("Copying in '%s' (%s) on block level into future partition %" PRIu64 ".",
+                         p->copy_blocks_path, FORMAT_BYTES(p->copy_blocks_size), p->partno);
 
                 r = copy_bytes_full(p->copy_blocks_fd, target_fd, p->copy_blocks_size, 0, NULL, NULL, NULL, NULL);
                 if (r < 0)
@@ -4352,7 +4347,7 @@ static int parse_argv(int argc, char *argv[]) {
                         return -EINVAL;
 
                 default:
-                        assert_not_reached("Unhandled option");
+                        assert_not_reached();
                 }
 
         if (argc - optind > 1)
@@ -4637,7 +4632,6 @@ static int resize_backing_fd(
                 const char *backing_file,   /* If the above refers to a loopback device, the backing regular file for that, which we can grow */
                 LoopDevice *loop_device) {
 
-        char buf1[FORMAT_BYTES_MAX], buf2[FORMAT_BYTES_MAX];
         _cleanup_close_ int writable_fd = -1;
         uint64_t current_size;
         struct stat st;
@@ -4678,11 +4672,9 @@ static int resize_backing_fd(
                 current_size = st.st_size;
         }
 
-        assert_se(format_bytes(buf1, sizeof(buf1), current_size));
-        assert_se(format_bytes(buf2, sizeof(buf2), arg_size));
-
         if (current_size >= arg_size) {
-                log_info("File '%s' already is of requested size or larger, not growing. (%s >= %s)", node, buf1, buf2);
+                log_info("File '%s' already is of requested size or larger, not growing. (%s >= %s)",
+                         node, FORMAT_BYTES(current_size), FORMAT_BYTES(arg_size));
                 return 0;
         }
 
@@ -4705,7 +4697,8 @@ static int resize_backing_fd(
 
                 if ((uint64_t) st.st_size != current_size)
                         return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
-                                               "Size of backing file '%s' of loopback block device '%s' don't match, refusing.", node, backing_file);
+                                               "Size of backing file '%s' of loopback block device '%s' don't match, refusing.",
+                                               node, backing_file);
         } else {
                 assert(S_ISREG(st.st_mode));
                 assert(!backing_file);
@@ -4723,15 +4716,16 @@ static int resize_backing_fd(
                 if (fallocate(writable_fd, 0, 0, arg_size) < 0) {
                         if (!ERRNO_IS_NOT_SUPPORTED(errno))
                                 return log_error_errno(errno, "Failed to grow '%s' from %s to %s by allocation: %m",
-                                                       node, buf1, buf2);
+                                                       node, FORMAT_BYTES(current_size), FORMAT_BYTES(arg_size));
 
                         /* Fallback to truncation, if fallocate() is not supported. */
                         log_debug("Backing file system does not support fallocate(), falling back to ftruncate().");
                 } else {
                         if (current_size == 0) /* Likely regular file just created by us */
-                                log_info("Allocated %s for '%s'.", buf2, node);
+                                log_info("Allocated %s for '%s'.", FORMAT_BYTES(arg_size), node);
                         else
-                                log_info("File '%s' grown from %s to %s by allocation.", node, buf1, buf2);
+                                log_info("File '%s' grown from %s to %s by allocation.",
+                                         node, FORMAT_BYTES(current_size), FORMAT_BYTES(arg_size));
 
                         goto done;
                 }
@@ -4739,12 +4733,13 @@ static int resize_backing_fd(
 
         if (ftruncate(writable_fd, arg_size) < 0)
                 return log_error_errno(errno, "Failed to grow '%s' from %s to %s by truncation: %m",
-                                       node, buf1, buf2);
+                                       node, FORMAT_BYTES(current_size), FORMAT_BYTES(arg_size));
 
         if (current_size == 0) /* Likely regular file just created by us */
-                log_info("Sized '%s' to %s.", node, buf2);
+                log_info("Sized '%s' to %s.", node, FORMAT_BYTES(arg_size));
         else
-                log_info("File '%s' grown from %s to %s by truncation.", node, buf1, buf2);
+                log_info("File '%s' grown from %s to %s by truncation.",
+                         node, FORMAT_BYTES(current_size), FORMAT_BYTES(arg_size));
 
 done:
         r = resize_pt(writable_fd);
@@ -4762,7 +4757,6 @@ done:
 
 static int determine_auto_size(Context *c) {
         uint64_t sum = round_up_size(GPT_METADATA_SIZE, 4096);
-        char buf[FORMAT_BYTES_MAX];
         Partition *p;
 
         assert_se(c);
@@ -4780,13 +4774,14 @@ static int determine_auto_size(Context *c) {
                 sum += m;
         }
 
-        assert_se(format_bytes(buf, sizeof(buf), sum));
-        if (c->total != UINT64_MAX) { /* Image already allocated? Then show its size */
-                char buf2[FORMAT_BYTES_MAX];
-                assert_se(format_bytes(buf2, sizeof(buf2), c->total));
-                log_info("Automatically determined minimal disk image size as %s, current image size is %s.", buf, buf2);
-        } else /* If the image is being created right now, then it has no previous size, suppress any comment about it hence */
-                log_info("Automatically determined minimal disk image size as %s.", buf);
+        if (c->total != UINT64_MAX)
+                /* Image already allocated? Then show its size. */
+                log_info("Automatically determined minimal disk image size as %s, current image size is %s.",
+                         FORMAT_BYTES(sum), FORMAT_BYTES(c->total));
+        else
+                /* If the image is being created right now, then it has no previous size, suppress any comment about it hence. */
+                log_info("Automatically determined minimal disk image size as %s.",
+                         FORMAT_BYTES(sum));
 
         arg_size = sum;
         return 0;
@@ -4962,11 +4957,9 @@ static int run(int argc, char *argv[]) {
                         break; /* Success! */
 
                 if (!context_drop_one_priority(context)) {
-                        char buf[FORMAT_BYTES_MAX];
                         r = log_error_errno(SYNTHETIC_ERRNO(ENOSPC),
                                             "Can't fit requested partitions into available free space (%s), refusing.",
-                                            format_bytes(buf, sizeof(buf), largest_free_area));
-
+                                            FORMAT_BYTES(largest_free_area));
                         determine_auto_size(context);
                         return r;
                 }
index aec75f1fb7b8df5e23d851a62c015c6812704246..0024a606112961b5db5bc49ef57755ffc28c67bf 100644 (file)
@@ -185,7 +185,7 @@ static int parse_argv(int argc, char *argv[]) {
                         return -EINVAL;
 
                 default:
-                        assert_not_reached("Unhandled option");
+                        assert_not_reached();
                 }
 
         return 1;
index 8f866f57e47a3d7c540ef22c7233b04570a25bba..de82f5bff7f5c8ab33e4944a41459ef516ab4955 100644 (file)
@@ -22,8 +22,8 @@ if conf.get('ENABLE_PORTABLED') == 1
         install_data('org.freedesktop.portable1.policy',
                      install_dir : polkitpolicydir)
 
-        install_data('profile/default/service.conf', install_dir : join_paths(profiledir, 'default'))
-        install_data('profile/nonetwork/service.conf', install_dir : join_paths(profiledir, 'nonetwork'))
-        install_data('profile/strict/service.conf', install_dir : join_paths(profiledir, 'strict'))
-        install_data('profile/trusted/service.conf', install_dir : join_paths(profiledir, 'trusted'))
+        install_data('profile/default/service.conf', install_dir : profiledir / 'default')
+        install_data('profile/nonetwork/service.conf', install_dir : profiledir / 'nonetwork')
+        install_data('profile/strict/service.conf', install_dir : profiledir / 'strict')
+        install_data('profile/trusted/service.conf', install_dir : profiledir / 'trusted')
 endif
index 4cf5fb4f0aa92bd74baa0b9d706aaa028fee1391..ba7fd58fc12bf4b8bbd50b9692f799ba77168c83 100644 (file)
@@ -86,10 +86,8 @@ static PortableMetadata *portable_metadata_new(const char *name, const char *pat
         /* In case of a layered attach, we want to remember which image the unit came from */
         if (path) {
                 m->image_path = strdup(path);
-                if (!m->image_path) {
-                        free(m);
-                        return NULL;
-                }
+                if (!m->image_path)
+                        return mfree(m);
         }
 
         strcpy(m->name, name);
@@ -483,7 +481,7 @@ static int portable_extract_by_path(
                                 assert(!os_release);
                                 os_release = TAKE_PTR(add);
                         } else
-                                assert_not_reached("Unexpected metadata item from child.");
+                                assert_not_reached();
                 }
 
                 r = wait_for_terminate_and_check("(sd-dissect)", child, 0);
index 2d8079ad97992ef795d688351aa0938bb8a45db9..c2d79ec3a23d90040060b8ce7368046c69b51cbd 100644 (file)
@@ -1288,7 +1288,7 @@ static int parse_argv(int argc, char *argv[]) {
                         return -EINVAL;
 
                 default:
-                        assert_not_reached("Unhandled option");
+                        assert_not_reached();
                 }
         }
 
index 93ded6d56437b3d51f34f3b19c3af22abef65a3c..4fdf445c98c996bd07c789fd72aa57b2afe860ce 100644 (file)
@@ -200,7 +200,7 @@ int resolvconf_parse_argv(int argc, char *argv[]) {
                         return -EINVAL;
 
                 default:
-                        assert_not_reached("Unhandled option");
+                        assert_not_reached();
                 }
 
         if (arg_mode == _MODE_INVALID)
index 7d13ed39050209d374811a7c8506cd82dead2d3e..196dccdba08e92306b409ba5331b3c12294b3017 100644 (file)
@@ -150,8 +150,6 @@ int ifname_resolvconf_mangle(const char *s) {
 }
 
 static void print_source(uint64_t flags, usec_t rtt) {
-        char rtt_str[FORMAT_TIMESTAMP_MAX];
-
         if (!arg_legend)
                 return;
 
@@ -167,11 +165,10 @@ static void print_source(uint64_t flags, usec_t rtt) {
                flags & SD_RESOLVED_MDNS_IPV4 ? " mDNS/IPv4" : "",
                flags & SD_RESOLVED_MDNS_IPV6 ? " mDNS/IPv6" : "");
 
-        assert_se(format_timespan(rtt_str, sizeof(rtt_str), rtt, 100));
-
         printf(" in %s.%s\n"
                "%s-- Data is authenticated: %s; Data was acquired via local or encrypted transport: %s%s\n",
-               rtt_str, ansi_normal(),
+               FORMAT_TIMESPAN(rtt, 100),
+               ansi_normal(),
                ansi_grey(),
                yes_no(flags & SD_RESOLVED_AUTHENTICATED),
                yes_no(flags & SD_RESOLVED_CONFIDENTIAL),
@@ -3012,7 +3009,7 @@ static int compat_parse_argv(int argc, char *argv[]) {
                         return -EINVAL;
 
                 default:
-                        assert_not_reached("Unhandled option");
+                        assert_not_reached();
                 }
 
         if (arg_type == 0 && arg_class != 0)
@@ -3264,7 +3261,7 @@ static int native_parse_argv(int argc, char *argv[]) {
                         return -EINVAL;
 
                 default:
-                        assert_not_reached("Unhandled option");
+                        assert_not_reached();
                 }
 
         if (arg_type == 0 && arg_class != 0)
@@ -3414,7 +3411,7 @@ static int compat_main(int argc, char *argv[], sd_bus *bus) {
                 return translate("revert", arg_ifname, 0, NULL, bus);
 
         case _MODE_INVALID:
-                assert_not_reached("invalid mode");
+                assert_not_reached();
         }
 
         return 0;
index 7226200f00664500bf02d776131f0ca11bacbc5c..8ad50ba29b4e6a7487a60d023589c27a8b45ebe7 100644 (file)
@@ -135,7 +135,7 @@ static int reply_query_state(DnsQuery *q) {
         case DNS_TRANSACTION_VALIDATING:
         case DNS_TRANSACTION_SUCCESS:
         default:
-                assert_not_reached("Impossible state");
+                assert_not_reached();
         }
 }
 
index 283c06345c59015256b1678494813b85a87c02dd..3afaaad9372cdf9a9d7d643fb25ab2683ae71663 100644 (file)
@@ -395,7 +395,7 @@ int config_parse_dnssd_txt(
                         break;
 
                 default:
-                        assert_not_reached("Unknown type of Txt config");
+                        assert_not_reached();
                 }
 
                 LIST_INSERT_AFTER(items, txt_data->txt, last, i);
index 91da5b65156e85f805582c3611728057e11f084b..fd7679f17dd8e378297e9f5734f45b81db8289ef 100644 (file)
@@ -1028,7 +1028,7 @@ int dnssec_verify_rrset_search(
                                 continue;
 
                         default:
-                                assert_not_reached("Unexpected DNSSEC validation result");
+                                assert_not_reached();
                         }
                 }
         }
index 6e7175c754769d0d327bac4964d5f9831817a09d..0b797ecb1a12549695f8b840167dde544ee05a7a 100644 (file)
@@ -332,7 +332,7 @@ static inline size_t udp_header_size(int af) {
         case AF_INET6:
                 return UDP6_PACKET_HEADER_SIZE;
         default:
-                assert_not_reached("Unexpected address family");
+                assert_not_reached();
         }
 }
 
index 178482727c3ecb95611bfa4de08fdc20bda851e7..26a3006a6c98e72dbbb78f547d72d291787f9f6f 100644 (file)
@@ -757,7 +757,7 @@ DnsScopeMatch dns_scope_good_domain(
         }
 
         default:
-                assert_not_reached("Unknown scope protocol");
+                assert_not_reached();
         }
 }
 
index 94a46570f2984ec9cbaa19d22a56925c79fb88ea..c9f148a2b99dc54182b5659c54b7d095d132ef4b 100644 (file)
@@ -58,7 +58,7 @@ int dns_search_domain_new(
                 break;
 
         default:
-                assert_not_reached("Unknown search domain type");
+                assert_not_reached();
         }
 
         d->linked = true;
@@ -135,7 +135,7 @@ void dns_search_domain_move_back_and_unmark(DnsSearchDomain *d) {
                 break;
 
         default:
-                assert_not_reached("Unknown search domain type");
+                assert_not_reached();
         }
 }
 
index e7a4bce71a4a196f960a775e0bdac983ed9ae5eb..04a8e92d7358d39845f651671c7c8da67da1f10e 100644 (file)
@@ -90,7 +90,7 @@ int dns_server_new(
                 break;
 
         default:
-                assert_not_reached("Unknown server type");
+                assert_not_reached();
         }
 
         s->linked = true;
@@ -158,7 +158,7 @@ void dns_server_unlink(DnsServer *s) {
                 s->manager->n_dns_servers--;
                 break;
         default:
-                assert_not_reached("Unknown server type");
+                assert_not_reached();
         }
 
         s->linked = false;
@@ -213,7 +213,7 @@ void dns_server_move_back_and_unmark(DnsServer *s) {
                 break;
 
         default:
-                assert_not_reached("Unknown server type");
+                assert_not_reached();
         }
 }
 
index 5b9d32f0013085758eb228541f089c8bc7232e85..cec2c24151619eaf1c65e6df20e365002114bb19 100644 (file)
@@ -813,7 +813,7 @@ static void dns_stub_query_complete(DnsQuery *q) {
         case DNS_TRANSACTION_PENDING:
         case DNS_TRANSACTION_VALIDATING:
         default:
-                assert_not_reached("Impossible state");
+                assert_not_reached();
         }
 
         dns_query_free(q);
index 9535a7ba4c69021046dcfbd2f7f4025f677570a5..c2ca181ab79ff6e2cf1b302e379cc1bbe61073ad 100644 (file)
@@ -1091,7 +1091,7 @@ void dns_transaction_process_reply(DnsTransaction *t, DnsPacket *p, bool encrypt
                 break;
 
         default:
-                assert_not_reached("Invalid DNS protocol.");
+                assert_not_reached();
         }
 
         if (t->received != p) {
@@ -1184,7 +1184,7 @@ void dns_transaction_process_reply(DnsTransaction *t, DnsPacket *p, bool encrypt
                 break;
 
         default:
-                assert_not_reached("Invalid DNS protocol.");
+                assert_not_reached();
         }
 
         if (DNS_PACKET_TC(p)) {
@@ -1528,7 +1528,7 @@ static int on_transaction_timeout(sd_event_source *s, usec_t usec, void *userdat
                         break;
 
                 default:
-                        assert_not_reached("Invalid DNS protocol.");
+                        assert_not_reached();
                 }
 
                 log_debug("Timeout reached on transaction %" PRIu16 ".", t->id);
@@ -1567,7 +1567,7 @@ static usec_t transaction_get_resend_timeout(DnsTransaction *t) {
                 return t->scope->resend_timeout;
 
         default:
-                assert_not_reached("Invalid DNS protocol.");
+                assert_not_reached();
         }
 }
 
@@ -1959,7 +1959,7 @@ int dns_transaction_go(DnsTransaction *t) {
                         accuracy = MDNS_JITTER_RANGE_USEC;
                         break;
                 default:
-                        assert_not_reached("bad protocol");
+                        assert_not_reached();
                 }
 
                 assert(!t->timeout_event_source);
@@ -3530,7 +3530,7 @@ int dns_transaction_validate_dnssec(DnsTransaction *t) {
                         break;
 
                 default:
-                        assert_not_reached("Unexpected NSEC result.");
+                        assert_not_reached();
                 }
         }
 
index 27d8c8967ec4072dd2569a67643905318a97d2c1..4a26f6b9febd2e369d053fc93b51c14af6868f0b 100644 (file)
@@ -78,7 +78,7 @@ static int reply_query_state(DnsQuery *q) {
         case DNS_TRANSACTION_VALIDATING:
         case DNS_TRANSACTION_SUCCESS:
         default:
-                assert_not_reached("Impossible state");
+                assert_not_reached();
         }
 }
 
index 3a0169a85f355b56d45f70b8edb1ad5952378fe2..caa2e45595058e0a24d825112d4885bb3ce74c1e 100644 (file)
@@ -46,31 +46,33 @@ OrderWithRequires(postun): systemd \
 
 %systemd_post() \
 %{expand:%%{?__systemd_someargs_%#:%%__systemd_someargs_%# systemd_post}} \
-if [ $1 -eq 1 ] && [ -x %{_bindir}/systemctl ]; then \
+if [ $1 -eq 1 ] && [ -x "{{SYSTEMD_UPDATE_HELPER_PATH}}" ]; then \
     # Initial installation \
-    %{_bindir}/systemctl --no-reload preset %{?*} || : \
+    {{SYSTEMD_UPDATE_HELPER_PATH}} install-system-units %{?*} || : \
 fi \
 %{nil}
 
-%systemd_user_post() %{expand:%systemd_post \\--global %%{?*}}
+%systemd_user_post() \
+%{expand:%%{?__systemd_someargs_%#:%%__systemd_someargs_%# systemd_user_post}} \
+if [ $1 -eq 1 ] && [ -x "{{SYSTEMD_UPDATE_HELPER_PATH}}" ]; then \
+    # Initial installation \
+    {{SYSTEMD_UPDATE_HELPER_PATH}} install-user-units %{?*} || : \
+fi \
+%{nil}
 
 %systemd_preun() \
 %{expand:%%{?__systemd_someargs_%#:%%__systemd_someargs_%# systemd_preun}} \
-if [ $1 -eq 0 ] && [ -x %{_bindir}/systemctl ]; then \
+if [ $1 -eq 0 ] && [ -x "{{SYSTEMD_UPDATE_HELPER_PATH}}" ]; then \
     # Package removal, not upgrade \
-    if [ -d /run/systemd/system ]; then \
-          %{_bindir}/systemctl --no-reload disable --now %{?*} || : \
-    else \
-          %{_bindir}/systemctl --no-reload disable %{?*} || : \
-    fi \
+    {{SYSTEMD_UPDATE_HELPER_PATH}} remove-system-units %{?*} || : \
 fi \
 %{nil}
 
 %systemd_user_preun() \
 %{expand:%%{?__systemd_someargs_%#:%%__systemd_someargs_%# systemd_user_preun}} \
-if [ $1 -eq 0 ] && [ -x %{_bindir}/systemctl ]; then \
+if [ $1 -eq 0 ] && [ -x "{{SYSTEMD_UPDATE_HELPER_PATH}}" ]; then \
     # Package removal, not upgrade \
-    %{_bindir}/systemctl --global disable %{?*} || : \
+    {{SYSTEMD_UPDATE_HELPER_PATH}} remove-user-units %{?*} || : \
 fi \
 %{nil}
 
@@ -84,16 +86,18 @@ fi \
 
 %systemd_postun_with_restart() \
 %{expand:%%{?__systemd_someargs_%#:%%__systemd_someargs_%# systemd_postun_with_restart}} \
-if [ $1 -ge 1 ] && [ -x %{_bindir}/systemctl ]; then \
+if [ $1 -ge 1 ] && [ -x "{{SYSTEMD_UPDATE_HELPER_PATH}}" ]; then \
     # Package upgrade, not uninstall \
-    for unit in %{?*}; do \
-         %{_bindir}/systemctl set-property $unit Markers=+needs-restart || : \
-    done \
+    {{SYSTEMD_UPDATE_HELPER_PATH}} mark-restart-system-units %{?*} || : \
 fi \
 %{nil}
 
 %systemd_user_postun_with_restart() \
-%{expand:%%{?__systemd_someargs_%#:%%__systemd_someargs_%# systemd_postun_with_restart}} \
+%{expand:%%{?__systemd_someargs_%#:%%__systemd_someargs_%# systemd_user_postun_with_restart}} \
+if [ $1 -ge 1 ] && [ -x "{{SYSTEMD_UPDATE_HELPER_PATH}}" ]; then \
+    # Package upgrade, not uninstall \
+    {{SYSTEMD_UPDATE_HELPER_PATH}} mark-restart-user-units %{?*} || : \
+fi \
 %{nil}
 
 %udev_hwdb_update() %{nil}
@@ -105,17 +109,17 @@ fi \
 # Deprecated. Use %tmpfiles_create_package instead
 %tmpfiles_create() \
 %{expand:%%{?__systemd_someargs_%#:%%__systemd_someargs_%# tmpfiles_create}} \
-[ -x %{_bindir}/systemd-tmpfiles ] && %{_bindir}/systemd-tmpfiles --create %{?*} || : \
+command -v systemd-tmpfiles >/dev/null && systemd-tmpfiles --create %{?*} || : \
 %{nil}
 
 # Deprecated. Use %sysusers_create_package instead
 %sysusers_create() \
 %{expand:%%{?__systemd_someargs_%#:%%__systemd_someargs_%# sysusers_create}} \
-[ -x %{_bindir}/systemd-sysusers ] && %{_bindir}/systemd-sysusers %{?*} || : \
+command -v systemd-sysusers >/dev/null && systemd-sysusers %{?*} || : \
 %{nil}
 
 %sysusers_create_inline() \
-[ -x %{_bindir}/systemd-sysusers ] && %{_bindir}/systemd-sysusers - <<SYSTEMD_INLINE_EOF || : \
+command -v systemd-sysusers >/dev/null && systemd-sysusers - <<SYSTEMD_INLINE_EOF || : \
 %{?*} \
 SYSTEMD_INLINE_EOF\
 %{nil}
index fc72fee73cc8ce98da11ce41e228f3923a9a238d..2ad3308cc1c6dc0310dda990767bc44c246d4a81 100644 (file)
@@ -1,9 +1,13 @@
 # SPDX-License-Identifier: LGPL-2.1-or-later
 
 in_files = [
-        ['macros.systemd',      rpmmacrosdir != 'no'],
-        ['triggers.systemd',    false],
-        ['triggers.systemd.sh', false]]
+        ['macros.systemd',        rpmmacrosdir != 'no', rpmmacrosdir],
+
+        # we conditionalize on rpmmacrosdir, but install into rootlibexecdir
+        ['systemd-update-helper', rpmmacrosdir != 'no', rootlibexecdir, 'rwxr-xr-x'],
+
+        ['triggers.systemd',      false],
+        ['triggers.systemd.sh',   false]]
 
 # The last two don't get installed anywhere, one of them needs to included in
 # the rpm spec file definition instead.
@@ -17,6 +21,7 @@ foreach tuple : in_files
                 command : [meson_render_jinja2, config_h, '@INPUT@'],
                 capture : true,
                 install : tuple[1],
-                install_dir : rpmmacrosdir,
+                install_dir : tuple.length() > 2 ? tuple[2] : '',
+                install_mode : tuple.length() > 3 ? tuple[3] : false,
                 build_by_default : true)
 endforeach
diff --git a/src/rpm/systemd-update-helper.in b/src/rpm/systemd-update-helper.in
new file mode 100755 (executable)
index 0000000..0c6675a
--- /dev/null
@@ -0,0 +1,116 @@
+#!/bin/bash
+set -eu
+set -o pipefail
+
+command="${1:?}"
+shift
+
+command -v systemctl >/dev/null || exit 0
+
+case "$command" in
+    install-system-units)
+        systemctl --no-reload preset "$@"
+        ;;
+
+    install-user-units)
+        systemctl --no-reload preset --global "$@"
+        ;;
+
+    remove-system-units)
+        if [ -d /run/systemd/system ]; then
+            systemctl --no-reload disable --now "$@"
+        else
+            systemctl --no-reload disable "$@"
+        fi
+        ;;
+
+    remove-user-units)
+        systemctl --global disable "$@"
+
+        [ -d /run/systemd/system ] || exit 0
+
+        users=$(systemctl list-units 'user@*' --legend=no | sed -n -r 's/.*user@([0-9]+).service.*/\1/p')
+        for user in $users; do
+            SYSTEMD_BUS_TIMEOUT={{UPDATE_HELPER_USER_TIMEOUT}} \
+                    systemctl --user -M "$user@" disable --now "$@" &
+        done
+        wait
+        ;;
+
+    mark-restart-system-units)
+        [ -d /run/systemd/system ] || exit 0
+
+        for unit in "$@"; do
+            systemctl set-property "$unit" Markers=+needs-restart &
+        done
+        wait
+        ;;
+
+    mark-restart-user-units)
+        [ -d /run/systemd/system ] || exit 0
+
+        users=$(systemctl list-units 'user@*' --legend=no | sed -n -r 's/.*user@([0-9]+).service.*/\1/p')
+        for user in $users; do
+            SYSTEMD_BUS_TIMEOUT={{UPDATE_HELPER_USER_TIMEOUT}} \
+                    systemctl --user -M "$user@" set-property "$unit" Markers=+needs-restart &
+        done
+        wait
+        ;;
+
+    system-reload-restart|system-reload|system-restart)
+        if [ -n "$*" ]; then
+            echo "Unexpected arguments for '$command': $*"
+            exit 2
+        fi
+
+        [ -d /run/systemd/system ] || exit 0
+
+        if [[ "$command" =~ reload ]]; then
+            systemctl daemon-reload
+        fi
+
+        if [[ "$command" =~ restart ]]; then
+            systemctl reload-or-restart --marked
+        fi
+        ;;
+
+    user-reload-restart|user-reload|user-restart|user-reexec)
+        if [ -n "$*" ]; then
+            echo "Unexpected arguments for '$command': $*"
+            exit 2
+        fi
+
+        [ -d /run/systemd/system ] || exit 0
+
+        users=$(systemctl list-units 'user@*' --legend=no | sed -n -r 's/.*user@([0-9]+).service.*/\1/p')
+
+        if [[ "$command" =~ reexec ]]; then
+            for user in $users; do
+                SYSTEMD_BUS_TIMEOUT={{UPDATE_HELPER_USER_TIMEOUT}} \
+                        systemctl --user -M "$user@" daemon-reexec &
+            done
+            wait
+        fi
+
+        if [[ "$command" =~ reload ]]; then
+            for user in $users; do
+                SYSTEMD_BUS_TIMEOUT={{UPDATE_HELPER_USER_TIMEOUT}} \
+                        systemctl --user -M "$user@" daemon-reload &
+            done
+            wait
+        fi
+
+        if [[ "$command" =~ restart ]]; then
+            for user in $users; do
+                SYSTEMD_BUS_TIMEOUT={{UPDATE_HELPER_USER_TIMEOUT}} \
+                        systemctl --user -M "$user@" reload-or-restart --marked &
+            done
+            wait
+        fi
+        ;;
+
+    *)
+        echo "Unknown verb '$command'"
+        exit 3
+        ;;
+esac
index b33d2212e8428c67fd48f7e15595b86d6c9a200b..8aeb2049c1d3f4f2ddf2e561a41a27b96c068155 100644 (file)
 -- upgraded. We care about the case where a package is initially
 -- installed, because other cases are covered by the *un scriptlets,
 -- so sometimes we will reload needlessly.
-if posix.access("/run/systemd/system") then
-    pid = posix.fork()
-    if pid == 0 then
-        assert(posix.exec("%{_bindir}/systemctl", "daemon-reload"))
-    elseif pid > 0 then
-        posix.wait(pid)
-    end
+pid = posix.fork()
+if pid == 0 then
+    assert(posix.exec("{{SYSTEMD_UPDATE_HELPER_PATH}}", "system-reload-restart"))
+elseif pid > 0 then
+    posix.wait(pid)
+end
 
-    pid = posix.fork()
-    if pid == 0 then
-        assert(posix.exec("%{_bindir}/systemctl", "reload-or-restart", "--marked"))
-    elseif pid > 0 then
-        posix.wait(pid)
-    end
+%transfiletriggerin -P 900899 -p <lua> -- {{USER_DATA_UNIT_DIR}} /etc/systemd/user
+pid = posix.fork()
+if pid == 0 then
+    assert(posix.exec("{{SYSTEMD_UPDATE_HELPER_PATH}}", "user-reload-restart"))
+elseif pid > 0 then
+    posix.wait(pid)
 end
 
 %transfiletriggerpostun -P 1000100 -p <lua> -- {{SYSTEM_DATA_UNIT_DIR}} /etc/systemd/system
@@ -35,24 +34,38 @@ end
 -- On upgrade, we need to run daemon-reload after any new unit files
 -- have been installed, but before %postun scripts in packages get
 -- executed.
-if posix.access("/run/systemd/system") then
-    pid = posix.fork()
-    if pid == 0 then
-        assert(posix.exec("%{_bindir}/systemctl", "daemon-reload"))
-    elseif pid > 0 then
-        posix.wait(pid)
-    end
+pid = posix.fork()
+if pid == 0 then
+    assert(posix.exec("{{SYSTEMD_UPDATE_HELPER_PATH}}", "system-reload"))
+elseif pid > 0 then
+    posix.wait(pid)
+end
+
+%transfiletriggerpostun -P 1000100 -p <lua> -- {{SYSTEM_DATA_UNIT_DIR}} /etc/systemd/system
+-- Execute daemon-reload in user managers.
+pid = posix.fork()
+if pid == 0 then
+    assert(posix.exec("{{SYSTEMD_UPDATE_HELPER_PATH}}", "user-reload"))
+elseif pid > 0 then
+    posix.wait(pid)
 end
 
 %transfiletriggerpostun -P 10000 -p <lua> -- {{SYSTEM_DATA_UNIT_DIR}} /etc/systemd/system
--- We restart remaining services that should be restarted here.
-if posix.access("/run/systemd/system") then
-    pid = posix.fork()
-    if pid == 0 then
-        assert(posix.exec("%{_bindir}/systemctl", "reload-or-restart", "--marked"))
-    elseif pid > 0 then
-        posix.wait(pid)
-    end
+-- We restart remaining system services that should be restarted here.
+pid = posix.fork()
+if pid == 0 then
+    assert(posix.exec("{{SYSTEMD_UPDATE_HELPER_PATH}}", "system-restart"))
+elseif pid > 0 then
+    posix.wait(pid)
+end
+
+%transfiletriggerpostun -P 9999 -p <lua> -- {{USER_DATA_UNIT_DIR}} /etc/systemd/user
+-- We restart remaining user services that should be restarted here.
+pid = posix.fork()
+if pid == 0 then
+    assert(posix.exec("{{SYSTEMD_UPDATE_HELPER_PATH}}", "user-restart"))
+elseif pid > 0 then
+    posix.wait(pid)
 end
 
 %transfiletriggerin -P 100700 -p <lua> -- {{SYSUSERS_DIR}}
@@ -62,7 +75,7 @@ end
 if posix.access("/run/systemd/system") then
     pid = posix.fork()
     if pid == 0 then
-        assert(posix.exec("%{_bindir}/systemd-sysusers"))
+        assert(posix.execp("systemd-sysusers"))
     elseif pid > 0 then
         posix.wait(pid)
     end
@@ -74,7 +87,7 @@ end
 if posix.access("/run/systemd/system") then
     pid = posix.fork()
     if pid == 0 then
-        assert(posix.exec("%{_bindir}/systemd-hwdb", "update"))
+        assert(posix.execp("systemd-hwdb", "update"))
     elseif pid > 0 then
         posix.wait(pid)
     end
@@ -86,7 +99,7 @@ end
 if posix.access("/run/systemd/system") then
     pid = posix.fork()
     if pid == 0 then
-        assert(posix.exec("%{_bindir}/journalctl", "--update-catalog"))
+        assert(posix.execp("journalctl", "--update-catalog"))
     elseif pid > 0 then
         posix.wait(pid)
     end
@@ -111,7 +124,7 @@ end
 if posix.access("/run/systemd/system") then
     pid = posix.fork()
     if pid == 0 then
-        assert(posix.exec("%{_bindir}/systemd-tmpfiles", "--create"))
+        assert(posix.execp("systemd-tmpfiles", "--create"))
     elseif pid > 0 then
         posix.wait(pid)
     end
@@ -123,7 +136,7 @@ end
 if posix.access("/run/systemd/system") then
     pid = posix.fork()
     if pid == 0 then
-        assert(posix.exec("%{_bindir}/udevadm", "control", "--reload"))
+        assert(posix.execp("udevadm", "control", "--reload"))
     elseif pid > 0 then
         posix.wait(pid)
     end
index 22abad9812b196ad0cdcda930c93d7a48d0027b8..694cd94e8d8ea5bb87228cf3a613e926f39c9b07 100644 (file)
 # upgraded. We care about the case where a package is initially
 # installed, because other cases are covered by the *un scriptlets,
 # so sometimes we will reload needlessly.
-if test -d "/run/systemd/system"; then
-  %{_bindir}/systemctl daemon-reload || :
-  %{_bindir}/systemctl reload-or-restart --marked || :
-fi
+{{SYSTEMD_UPDATE_HELPER_PATH}} system-reload-restart || :
+
+%transfiletriggerin -P 900899 -- {{USER_DATA_UNIT_DIR}} /etc/systemd/user
+{{SYSTEMD_UPDATE_HELPER_PATH}} user-reload-restart || :
 
 %transfiletriggerpostun -P 1000100 -- {{SYSTEM_DATA_UNIT_DIR}} /etc/systemd/system
 # On removal, we need to run daemon-reload after any units have been
@@ -25,36 +25,40 @@ fi
 # On upgrade, we need to run daemon-reload after any new unit files
 # have been installed, but before %postun scripts in packages get
 # executed.
-if test -d "/run/systemd/system"; then
-  %{_bindir}/systemctl daemon-reload || :
-fi
+{{SYSTEMD_UPDATE_HELPER_PATH}} system-reload || :
+
+%transfiletriggerpostun -P 1000099 -- {{USER_DATA_UNIT_DIR}} /etc/systemd/user
+# Execute daemon-reload in user managers.
+{{SYSTEMD_UPDATE_HELPER_PATH}} user-reload || :
 
 %transfiletriggerpostun -P 10000 -- {{SYSTEM_DATA_UNIT_DIR}} /etc/systemd/system
-# We restart remaining services that should be restarted here.
-if test -d "/run/systemd/system"; then
-  %{_bindir}/systemctl reload-or-restart --marked || :
-fi
+# We restart remaining system services that should be restarted here.
+{{SYSTEMD_UPDATE_HELPER_PATH}} system-restart || :
+
+%transfiletriggerpostun -P  9999 -- {{USER_DATA_UNIT_DIR}} /etc/systemd/user
+# We restart remaining user services that should be restarted here.
+{{SYSTEMD_UPDATE_HELPER_PATH}} user-restart || :
 
 %transfiletriggerin -P 1000700 -- {{SYSUSERS_DIR}}
 # This script will process files installed in {{SYSUSERS_DIR}} to create
 # specified users automatically. The priority is set such that it
 # will run before the tmpfiles file trigger.
 if test -d "/run/systemd/system"; then
-  %{_bindir}/systemd-sysusers || :
+  systemd-sysusers || :
 fi
 
 %transfiletriggerin -P 1000700 udev -- {{UDEV_HWDB_DIR}}
 # This script will automatically invoke hwdb update if files have been
 # installed or updated in {{UDEV_HWDB_DIR}}.
 if test -d "/run/systemd/system"; then
-  %{_bindir}/systemd-hwdb update || :
+  systemd-hwdb update || :
 fi
 
 %transfiletriggerin -P 1000700 -- {{SYSTEMD_CATALOG_DIR}}
 # This script will automatically invoke journal catalog update if files
 # have been installed or updated in {{SYSTEMD_CATALOG_DIR}}.
 if test -d "/run/systemd/system"; then
-  %{_bindir}/journalctl --update-catalog || :
+  journalctl --update-catalog || :
 fi
 
 %transfiletriggerin -P 1000700 -- {{BINFMT_DIR}}
@@ -71,14 +75,14 @@ fi
 # tmpfiles automatically. The priority is set such that it will run
 # after the sysusers file trigger, but before any other triggers.
 if test -d "/run/systemd/system"; then
-  %{_bindir}/systemd-tmpfiles --create || :
+  systemd-tmpfiles --create || :
 fi
 
 %transfiletriggerin -P 1000600 udev -- {{UDEV_RULES_DIR}}
 # This script will automatically update udev with new rules if files
 # have been installed or updated in {{UDEV_RULES_DIR}}.
 if test -e /run/udev/control; then
-  %{_bindir}/udevadm control --reload || :
+  udevadm control --reload || :
 fi
 
 %transfiletriggerin -P 1000500 -- {{SYSCTL_DIR}}
index 38de0322e0feb8408cca5dbaa5cb8a339071c2b2..0be974f03ab66822e0f929e506a758a3b49f2613 100644 (file)
@@ -503,7 +503,7 @@ static int parse_argv(int argc, char *argv[]) {
                         return -EINVAL;
 
                 default:
-                        assert_not_reached("Unhandled option");
+                        assert_not_reached();
                 }
 
         with_trigger = !!arg_path_property || !!arg_socket_property || arg_with_timer;
@@ -1155,7 +1155,7 @@ static int start_transient_service(
                         if (!pty_path)
                                 return log_oom();
                 } else
-                        assert_not_reached("Can't allocate tty via ssh");
+                        assert_not_reached();
         }
 
         /* Optionally, wait for the start job to complete. If we are supposed to read the service's stdin
@@ -1322,34 +1322,25 @@ static int start_transient_service(
 
                         if (timestamp_is_set(c.inactive_enter_usec) &&
                             timestamp_is_set(c.inactive_exit_usec) &&
-                            c.inactive_enter_usec > c.inactive_exit_usec) {
-                                char ts[FORMAT_TIMESPAN_MAX];
+                            c.inactive_enter_usec > c.inactive_exit_usec)
                                 log_info("Service runtime: %s",
-                                         format_timespan(ts, sizeof ts, c.inactive_enter_usec - c.inactive_exit_usec, USEC_PER_MSEC));
-                        }
+                                         FORMAT_TIMESPAN(c.inactive_enter_usec - c.inactive_exit_usec, USEC_PER_MSEC));
 
-                        if (c.cpu_usage_nsec != NSEC_INFINITY) {
-                                char ts[FORMAT_TIMESPAN_MAX];
+                        if (c.cpu_usage_nsec != NSEC_INFINITY)
                                 log_info("CPU time consumed: %s",
-                                         format_timespan(ts, sizeof ts, DIV_ROUND_UP(c.cpu_usage_nsec, NSEC_PER_USEC), USEC_PER_MSEC));
-                        }
+                                         FORMAT_TIMESPAN(DIV_ROUND_UP(c.cpu_usage_nsec, NSEC_PER_USEC), USEC_PER_MSEC));
 
-                        if (c.ip_ingress_bytes != UINT64_MAX) {
-                                char bytes[FORMAT_BYTES_MAX];
-                                log_info("IP traffic received: %s", format_bytes(bytes, sizeof bytes, c.ip_ingress_bytes));
-                        }
-                        if (c.ip_egress_bytes != UINT64_MAX) {
-                                char bytes[FORMAT_BYTES_MAX];
-                                log_info("IP traffic sent: %s", format_bytes(bytes, sizeof bytes, c.ip_egress_bytes));
-                        }
-                        if (c.io_read_bytes != UINT64_MAX) {
-                                char bytes[FORMAT_BYTES_MAX];
-                                log_info("IO bytes read: %s", format_bytes(bytes, sizeof bytes, c.io_read_bytes));
-                        }
-                        if (c.io_write_bytes != UINT64_MAX) {
-                                char bytes[FORMAT_BYTES_MAX];
-                                log_info("IO bytes written: %s", format_bytes(bytes, sizeof bytes, c.io_write_bytes));
-                        }
+                        if (c.ip_ingress_bytes != UINT64_MAX)
+                                log_info("IP traffic received: %s", FORMAT_BYTES(c.ip_ingress_bytes));
+
+                        if (c.ip_egress_bytes != UINT64_MAX)
+                                log_info("IP traffic sent: %s", FORMAT_BYTES(c.ip_egress_bytes));
+
+                        if (c.io_read_bytes != UINT64_MAX)
+                                log_info("IO bytes read: %s", FORMAT_BYTES(c.io_read_bytes));
+
+                        if (c.io_write_bytes != UINT64_MAX)
+                                log_info("IO bytes written: %s", FORMAT_BYTES(c.io_write_bytes));
                 }
 
                 /* Try to propagate the service's return value. But if the service defines
@@ -1637,7 +1628,7 @@ static int start_transient_trigger(
         else if (streq(suffix, ".timer"))
                 r = transient_timer_set_properties(m);
         else
-                assert_not_reached("Invalid suffix");
+                assert_not_reached();
         if (r < 0)
                 return r;
 
index 10e1857649403a0380b33b8a97d2b83958c6a7f8..3f286a888b5cd44adf65c938bacd1659c5bae7a4 100644 (file)
@@ -320,7 +320,7 @@ static int acl_entry_equal(acl_entry_t a, acl_entry_t b) {
                 return *gid_a == *gid_b;
         }
         default:
-                assert_not_reached("Unknown acl tag type");
+                assert_not_reached();
         }
 }
 
index 0f865a71689a38f89134a3e406847975c544b80f..4575bb4e2ff21ca33087eb0cfdc5a1b08163c559 100644 (file)
@@ -426,6 +426,7 @@ int bpf_program_deserialize_attachment(const char *v, FDSet *fds, BPFProgram **b
         _cleanup_free_ char *sfd = NULL, *sat = NULL, *unescaped = NULL;
         _cleanup_(bpf_program_unrefp) BPFProgram *p = NULL;
         _cleanup_close_ int fd = -1;
+        ssize_t l;
         int ifd, at, r;
 
         assert(v);
@@ -456,9 +457,9 @@ int bpf_program_deserialize_attachment(const char *v, FDSet *fds, BPFProgram **b
                 return at;
 
         /* The rest is the path */
-        r = cunescape(v, 0, &unescaped);
-        if (r < 0)
-                return r;
+        l = cunescape(v, 0, &unescaped);
+        if (l < 0)
+                return l;
 
         fd = fdset_remove(fds, ifd);
         if (fd < 0)
index f4e291385bebb5bd826abce8f5524f5faf9996e1..00a6a37ff70925d63aaa583254a20d46f1054a19 100644 (file)
@@ -1613,7 +1613,7 @@ int btrfs_subvol_snapshot_fd_full(
                         return -EISDIR;
 
                 r = btrfs_subvol_make(new_path);
-                if (r == -ENOTTY && (flags & BTRFS_SNAPSHOT_FALLBACK_DIRECTORY)) {
+                if (ERRNO_IS_NOT_SUPPORTED(r) && (flags & BTRFS_SNAPSHOT_FALLBACK_DIRECTORY)) {
                         /* If the destination doesn't support subvolumes, then use a plain directory, if that's requested. */
                         if (mkdir(new_path, 0755) < 0)
                                 return -errno;
@@ -1624,8 +1624,15 @@ int btrfs_subvol_snapshot_fd_full(
 
                 r = copy_directory_fd_full(
                                 old_fd, new_path,
-                                COPY_MERGE|COPY_REFLINK|COPY_SAME_MOUNT|COPY_HARDLINKS|(FLAGS_SET(flags, BTRFS_SNAPSHOT_SIGINT) ? COPY_SIGINT : 0),
-                                progress_path, progress_bytes, userdata);
+                                COPY_MERGE_EMPTY|
+                                COPY_REFLINK|
+                                COPY_SAME_MOUNT|
+                                COPY_HARDLINKS|
+                                (FLAGS_SET(flags, BTRFS_SNAPSHOT_SIGINT) ? COPY_SIGINT : 0)|
+                                (FLAGS_SET(flags, BTRFS_SNAPSHOT_SIGTERM) ? COPY_SIGTERM : 0),
+                                progress_path,
+                                progress_bytes,
+                                userdata);
                 if (r < 0)
                         goto fallback_fail;
 
index 7b18f57719aa5cd660fed09a5d07c64febd44653..b67a4c10fe83424f44389fe1774267a778b3bcd6 100644 (file)
@@ -35,6 +35,7 @@ typedef enum BtrfsSnapshotFlags {
         BTRFS_SNAPSHOT_FALLBACK_DIRECTORY = 1 << 4, /* If the destination doesn't support subvolumes, reflink/copy instead */
         BTRFS_SNAPSHOT_FALLBACK_IMMUTABLE = 1 << 5, /* When we can't create a subvolume, use the FS_IMMUTABLE attribute for indicating read-only */
         BTRFS_SNAPSHOT_SIGINT             = 1 << 6, /* Check for SIGINT regularly, and return EINTR if seen */
+        BTRFS_SNAPSHOT_SIGTERM            = 1 << 7, /* Ditto, but for SIGTERM */
 } BtrfsSnapshotFlags;
 
 typedef enum BtrfsRemoveFlags {
index b45921943a8689af1a053ed839a0c56ef01d16f6..4e401180e9a582a03dbe23fb940e73722e200275 100644 (file)
@@ -105,20 +105,14 @@ static int bus_print_property(const char *name, const char *expected_value, sd_b
                  * should it turn out to not be sufficient */
 
                 if (endswith(name, "Timestamp") ||
-                    STR_IN_SET(name, "NextElapseUSecRealtime", "LastTriggerUSec", "TimeUSec", "RTCTimeUSec")) {
-                        char timestamp[FORMAT_TIMESTAMP_MAX];
-                        const char *t;
+                    STR_IN_SET(name, "NextElapseUSecRealtime", "LastTriggerUSec", "TimeUSec", "RTCTimeUSec"))
 
-                        t = format_timestamp(timestamp, sizeof(timestamp), u);
-                        bus_print_property_value(name, expected_value, flags, t);
+                        bus_print_property_value(name, expected_value, flags, FORMAT_TIMESTAMP(u));
 
-                } else if (strstr(name, "USec")) {
-                        char timespan[FORMAT_TIMESPAN_MAX];
+                else if (strstr(name, "USec"))
+                        bus_print_property_value(name, expected_value, flags, FORMAT_TIMESPAN(u, 0));
 
-                        (void) format_timespan(timespan, sizeof(timespan), u, 0);
-                        bus_print_property_value(name, expected_value, flags, timespan);
-
-                } else if (streq(name, "CoredumpFilter"))
+                else if (streq(name, "CoredumpFilter"))
                         bus_print_property_valuef(name, expected_value, flags, "0x%"PRIx64, u);
 
                 else if (streq(name, "RestrictNamespaces")) {
index a97ffbcea45410d1392a6c81725ffba45dcb6750..1ff1e7600d76ed7beed344a6c9c3ad4bef531241 100644 (file)
@@ -1096,7 +1096,7 @@ static int bus_append_execute_property(sd_bus_message *m, const char *field, con
                                 r = sd_bus_message_append_array(m, 'y', decoded, decoded_size);
                         } else {
                                 _cleanup_free_ char *unescaped = NULL;
-                                int l;
+                                ssize_t l;
 
                                 l = cunescape(p, UNESCAPE_ACCEPT_NUL, &unescaped);
                                 if (l < 0)
@@ -1233,18 +1233,19 @@ static int bus_append_execute_property(sd_bus_message *m, const char *field, con
 
         if (streq(field, "StandardInputText")) {
                 _cleanup_free_ char *unescaped = NULL;
+                ssize_t l;
 
-                r = cunescape(eq, 0, &unescaped);
-                if (r < 0)
-                        return log_error_errno(r, "Failed to unescape text '%s': %m", eq);
+                l = cunescape(eq, 0, &unescaped);
+                if (l < 0)
+                        return log_error_errno(l, "Failed to unescape text '%s': %m", eq);
 
                 if (!strextend(&unescaped, "\n"))
                         return log_oom();
 
-                /* Note that we don't expand specifiers here, but that should be OK, as this is a programmatic
-                 * interface anyway */
+                /* Note that we don't expand specifiers here, but that should be OK, as this is a
+                 * programmatic interface anyway */
 
-                return bus_append_byte_array(m, field, unescaped, strlen(unescaped));
+                return bus_append_byte_array(m, field, unescaped, l + 1);
         }
 
         if (streq(field, "StandardInputData")) {
index 64ca67993c00e714305b63fb3e32fba3bccea02e..942a59be88cac2d17a446287b81ff40a10ff8e77 100644 (file)
@@ -291,7 +291,7 @@ int bus_connect_transport(
                 break;
 
         default:
-                assert_not_reached("Hmm, unknown transport type.");
+                assert_not_reached();
         }
         if (r < 0)
                 return r;
@@ -337,7 +337,7 @@ int bus_connect_transport_systemd(BusTransport transport, const char *host, bool
                 break;
 
         default:
-                assert_not_reached("Hmm, unknown transport type.");
+                assert_not_reached();
         }
 
         return r;
index b446daf5819731c02af0432fce2ac58b22a13e17..7c1c48d0690030db1b154cbb31540ace8da39ac1 100644 (file)
@@ -139,10 +139,15 @@ int clock_reset_timewarp(void) {
 
 #define EPOCH_FILE "/usr/lib/clock-epoch"
 
-int clock_apply_epoch(void) {
+int clock_apply_epoch(ClockChangeDirection *ret_attempted_change) {
         struct stat st;
         struct timespec ts;
-        usec_t epoch_usec;
+        usec_t epoch_usec, now_usec;
+
+        /* NB: we update *ret_attempted_change in *all* cases, both
+         * on success and failure, to indicate what we intended to do! */
+
+        assert(ret_attempted_change);
 
         if (stat(EPOCH_FILE, &st) < 0) {
                 if (errno != ENOENT)
@@ -152,8 +157,15 @@ int clock_apply_epoch(void) {
         } else
                 epoch_usec = timespec_load(&st.st_mtim);
 
-        if (now(CLOCK_REALTIME) >= epoch_usec)
+        now_usec = now(CLOCK_REALTIME);
+        if (now_usec < epoch_usec)
+                *ret_attempted_change = CLOCK_CHANGE_FORWARD;
+        else if (now_usec > usec_add(epoch_usec, CLOCK_VALID_RANGE_USEC_MAX))
+                *ret_attempted_change = CLOCK_CHANGE_BACKWARD;
+        else {
+                *ret_attempted_change = CLOCK_CHANGE_NOOP;
                 return 0;
+        }
 
         if (clock_settime(CLOCK_REALTIME, timespec_store(&ts, epoch_usec)) < 0)
                 return -errno;
index 9e96d50d963c0b2e55ecb588c42762fd0767ab4e..c8f6d1b1f1e6089fb076dde37fa102a6dce30b50 100644 (file)
@@ -1,11 +1,20 @@
 /* SPDX-License-Identifier: LGPL-2.1-or-later */
 #pragma once
 
+#include <errno.h>
 #include <time.h>
 
+typedef enum ClockChangeDirection {
+        CLOCK_CHANGE_NOOP,
+        CLOCK_CHANGE_FORWARD,
+        CLOCK_CHANGE_BACKWARD,
+        _CLOCK_CHANGE_MAX,
+        _CLOCK_CHANGE_INVALID = -EINVAL,
+} ClockChangeDirection;
+
 int clock_is_localtime(const char* adjtime_path);
 int clock_set_timezone(int *ret_minutesdelta);
 int clock_reset_timewarp(void);
 int clock_get_hwclock(struct tm *tm);
 int clock_set_hwclock(const struct tm *tm);
-int clock_apply_epoch(void);
+int clock_apply_epoch(ClockChangeDirection *ret_attempted_change);
index ec9d57b292a8da92273dc0d62a626bf7ce8ec302..1d28f7ba5795d4b819857e7cdeea8b87b1e34a8f 100644 (file)
@@ -202,7 +202,7 @@ static bool test_order(int k, OrderOperator p) {
                 return k > 0;
 
         default:
-                assert_not_reached("unknown order");
+                assert_not_reached();
 
         }
 }
index 65d75a15d54a514355d6220b65e4e49c71bd6aff..a01b6df1b22354f86ab9dc49f5d2b4d949702752 100644 (file)
@@ -88,6 +88,23 @@ static int fd_is_nonblock_pipe(int fd) {
         return FLAGS_SET(flags, O_NONBLOCK) ? FD_IS_NONBLOCKING_PIPE : FD_IS_BLOCKING_PIPE;
 }
 
+static int look_for_signals(CopyFlags copy_flags) {
+        int r;
+
+        if ((copy_flags & (COPY_SIGINT|COPY_SIGTERM)) == 0)
+                return 0;
+
+        r = pop_pending_signal(copy_flags & COPY_SIGINT ? SIGINT : 0,
+                               copy_flags & COPY_SIGTERM ? SIGTERM : 0);
+        if (r < 0)
+                return r;
+        if (r != 0)
+                return log_debug_errno(SYNTHETIC_ERRNO(EINTR),
+                                       "Got %s, cancelling copy operation.", signal_to_string(r));
+
+        return 0;
+}
+
 int copy_bytes_full(
                 int fdf, int fdt,
                 uint64_t max_bytes,
@@ -176,13 +193,9 @@ int copy_bytes_full(
                 if (max_bytes <= 0)
                         return 1; /* return > 0 if we hit the max_bytes limit */
 
-                if (FLAGS_SET(copy_flags, COPY_SIGINT)) {
-                        r = pop_pending_signal(SIGINT);
-                        if (r < 0)
-                                return r;
-                        if (r > 0)
-                                return -EINTR;
-                }
+                r = look_for_signals(copy_flags);
+                if (r < 0)
+                        return r;
 
                 if (max_bytes != UINT64_MAX && m > max_bytes)
                         m = max_bytes;
@@ -627,10 +640,8 @@ static int fd_copy_regular(
                 return -errno;
 
         r = copy_bytes_full(fdf, fdt, UINT64_MAX, copy_flags, NULL, NULL, progress, userdata);
-        if (r < 0) {
-                (void) unlinkat(dt, to, 0);
-                return r;
-        }
+        if (r < 0)
+                goto fail;
 
         if (fchown(fdt,
                    uid_is_valid(override_uid) ? override_uid : st->st_uid,
@@ -643,16 +654,25 @@ static int fd_copy_regular(
         (void) futimens(fdt, (struct timespec[]) { st->st_atim, st->st_mtim });
         (void) copy_xattr(fdf, fdt);
 
-        q = close(fdt);
-        fdt = -1;
+        if (copy_flags & COPY_FSYNC) {
+                if (fsync(fdt) < 0) {
+                        r = -errno;
+                        goto fail;
+                }
+        }
 
+        q = close_nointr(TAKE_FD(fdt)); /* even if this fails, the fd is now invalidated */
         if (q < 0) {
-                r = -errno;
-                (void) unlinkat(dt, to, 0);
+                r = q;
+                goto fail;
         }
 
         (void) memorize_hardlink(hardlink_context, st, dt, to);
         return r;
+
+fail:
+        (void) unlinkat(dt, to, 0);
+        return r;
 }
 
 static int fd_copy_fifo(
@@ -845,13 +865,9 @@ static int fd_copy_directory(
                 if (dot_or_dot_dot(de->d_name))
                         continue;
 
-                if (FLAGS_SET(copy_flags, COPY_SIGINT)) {
-                        r = pop_pending_signal(SIGINT);
-                        if (r < 0)
-                                return r;
-                        if (r > 0)
-                                return -EINTR;
-                }
+                r = look_for_signals(copy_flags);
+                if (r < 0)
+                        return r;
 
                 if (fstatat(dirfd(d), de->d_name, &buf, AT_SYMLINK_NOFOLLOW) < 0) {
                         r = -errno;
@@ -912,7 +928,7 @@ static int fd_copy_directory(
                 else
                         q = -EOPNOTSUPP;
 
-                if (q == -EINTR) /* Propagate SIGINT up instantly */
+                if (q == -EINTR) /* Propagate SIGINT/SIGTERM up instantly */
                         return q;
                 if (q == -EEXIST && (copy_flags & COPY_MERGE))
                         q = 0;
@@ -933,6 +949,11 @@ static int fd_copy_directory(
                 (void) futimens(fdt, (struct timespec[]) { st->st_atim, st->st_mtim });
         }
 
+        if (copy_flags & COPY_FSYNC_FULL) {
+                if (fsync(fdt) < 0)
+                        return -errno;
+        }
+
         return r;
 }
 
@@ -949,6 +970,7 @@ int copy_tree_at_full(
                 void *userdata) {
 
         struct stat st;
+        int r;
 
         assert(from);
         assert(to);
@@ -957,17 +979,47 @@ int copy_tree_at_full(
                 return -errno;
 
         if (S_ISREG(st.st_mode))
-                return fd_copy_regular(fdf, from, &st, fdt, to, override_uid, override_gid, copy_flags, NULL, progress_bytes, userdata);
+                r = fd_copy_regular(fdf, from, &st, fdt, to, override_uid, override_gid, copy_flags, NULL, progress_bytes, userdata);
         else if (S_ISDIR(st.st_mode))
-                return fd_copy_directory(fdf, from, &st, fdt, to, st.st_dev, COPY_DEPTH_MAX, override_uid, override_gid, copy_flags, NULL, NULL, progress_path, progress_bytes, userdata);
+                r = fd_copy_directory(fdf, from, &st, fdt, to, st.st_dev, COPY_DEPTH_MAX, override_uid, override_gid, copy_flags, NULL, NULL, progress_path, progress_bytes, userdata);
         else if (S_ISLNK(st.st_mode))
-                return fd_copy_symlink(fdf, from, &st, fdt, to, override_uid, override_gid, copy_flags);
+                r = fd_copy_symlink(fdf, from, &st, fdt, to, override_uid, override_gid, copy_flags);
         else if (S_ISFIFO(st.st_mode))
-                return fd_copy_fifo(fdf, from, &st, fdt, to, override_uid, override_gid, copy_flags, NULL);
+                r = fd_copy_fifo(fdf, from, &st, fdt, to, override_uid, override_gid, copy_flags, NULL);
         else if (S_ISBLK(st.st_mode) || S_ISCHR(st.st_mode) || S_ISSOCK(st.st_mode))
-                return fd_copy_node(fdf, from, &st, fdt, to, override_uid, override_gid, copy_flags, NULL);
+                r = fd_copy_node(fdf, from, &st, fdt, to, override_uid, override_gid, copy_flags, NULL);
         else
                 return -EOPNOTSUPP;
+        if (r < 0)
+                return r;
+
+        if (S_ISDIR(st.st_mode) && (copy_flags & COPY_SYNCFS)) {
+                /* If the top-level inode is a directory run syncfs() now. */
+                r = syncfs_path(fdt, to);
+                if (r < 0)
+                        return r;
+        } else if ((copy_flags & (COPY_FSYNC_FULL|COPY_SYNCFS)) != 0) {
+                /* fsync() the parent dir of what we just copied if COPY_FSYNC_FULL is set. Also do this in
+                 * case COPY_SYNCFS is set but the top-level inode wasn't actually a directory. We do this so that
+                 * COPY_SYNCFS provides reasonable synchronization semantics on any kind of inode: when the
+                 * copy operation is done the whole inode — regardless of its type — and all its children
+                 * will be synchronized to disk. */
+                r = fsync_parent_at(fdt, to);
+                if (r < 0)
+                        return r;
+        }
+
+        return 0;
+}
+
+static int sync_dir_by_flags(const char *path, CopyFlags copy_flags) {
+
+        if (copy_flags & COPY_SYNCFS)
+                return syncfs_path(AT_FDCWD, path);
+        if (copy_flags & COPY_FSYNC_FULL)
+                return fsync_parent_at(AT_FDCWD, path);
+
+        return 0;
 }
 
 int copy_directory_fd_full(
@@ -991,7 +1043,26 @@ int copy_directory_fd_full(
         if (r < 0)
                 return r;
 
-        return fd_copy_directory(dirfd, NULL, &st, AT_FDCWD, to, st.st_dev, COPY_DEPTH_MAX, UID_INVALID, GID_INVALID, copy_flags, NULL, NULL, progress_path, progress_bytes, userdata);
+        r = fd_copy_directory(
+                        dirfd, NULL,
+                        &st,
+                        AT_FDCWD, to,
+                        st.st_dev,
+                        COPY_DEPTH_MAX,
+                        UID_INVALID, GID_INVALID,
+                        copy_flags,
+                        NULL, NULL,
+                        progress_path,
+                        progress_bytes,
+                        userdata);
+        if (r < 0)
+                return r;
+
+        r = sync_dir_by_flags(to, copy_flags);
+        if (r < 0)
+                return r;
+
+        return 0;
 }
 
 int copy_directory_full(
@@ -1015,7 +1086,26 @@ int copy_directory_full(
         if (r < 0)
                 return r;
 
-        return fd_copy_directory(AT_FDCWD, from, &st, AT_FDCWD, to, st.st_dev, COPY_DEPTH_MAX, UID_INVALID, GID_INVALID, copy_flags, NULL, NULL, progress_path, progress_bytes, userdata);
+        r = fd_copy_directory(
+                        AT_FDCWD, from,
+                        &st,
+                        AT_FDCWD, to,
+                        st.st_dev,
+                        COPY_DEPTH_MAX,
+                        UID_INVALID, GID_INVALID,
+                        copy_flags,
+                        NULL, NULL,
+                        progress_path,
+                        progress_bytes,
+                        userdata);
+        if (r < 0)
+                return r;
+
+        r = sync_dir_by_flags(to, copy_flags);
+        if (r < 0)
+                return r;
+
+        return 0;
 }
 
 int copy_file_fd_full(
@@ -1026,6 +1116,7 @@ int copy_file_fd_full(
                 void *userdata) {
 
         _cleanup_close_ int fdf = -1;
+        struct stat st;
         int r;
 
         assert(from);
@@ -1035,12 +1126,32 @@ int copy_file_fd_full(
         if (fdf < 0)
                 return -errno;
 
+        r = fd_verify_regular(fdf);
+        if (r < 0)
+                return r;
+
+        if (fstat(fdt, &st) < 0)
+                return -errno;
+
         r = copy_bytes_full(fdf, fdt, UINT64_MAX, copy_flags, NULL, NULL, progress_bytes, userdata);
+        if (r < 0)
+                return r;
 
-        (void) copy_times(fdf, fdt, copy_flags);
-        (void) copy_xattr(fdf, fdt);
+        if (S_ISREG(fdt)) {
+                (void) copy_times(fdf, fdt, copy_flags);
+                (void) copy_xattr(fdf, fdt);
+        }
 
-        return r;
+        if (copy_flags & COPY_FSYNC_FULL) {
+                r = fsync_full(fdt);
+                if (r < 0)
+                        return r;
+        } else if (copy_flags & COPY_FSYNC) {
+                if (fsync(fdt) < 0)
+                        return -errno;
+        }
+
+        return 0;
 }
 
 int copy_file_full(
@@ -1054,9 +1165,9 @@ int copy_file_full(
                 copy_progress_bytes_t progress_bytes,
                 void *userdata) {
 
-        _cleanup_close_ int fdf = -1;
+        _cleanup_close_ int fdf = -1, fdt = -1;
         struct stat st;
-        int r, fdt = -1;  /* avoid false maybe-uninitialized warning */
+        int r;
 
         assert(from);
         assert(to);
@@ -1065,9 +1176,12 @@ int copy_file_full(
         if (fdf < 0)
                 return -errno;
 
-        if (mode == MODE_INVALID)
-                if (fstat(fdf, &st) < 0)
-                        return -errno;
+        if (fstat(fdf, &st) < 0)
+                return -errno;
+
+        r = stat_verify_regular(&st);
+        if (r < 0)
+                return r;
 
         RUN_WITH_UMASK(0000) {
                 if (copy_flags & COPY_MAC_CREATE) {
@@ -1083,15 +1197,18 @@ int copy_file_full(
                         return -errno;
         }
 
+        if (!FLAGS_SET(flags, O_EXCL)) { /* if O_EXCL was used we created the thing as regular file, no need to check again */
+                r = fd_verify_regular(fdt);
+                if (r < 0)
+                        goto fail;
+        }
+
         if (chattr_mask != 0)
                 (void) chattr_fd(fdt, chattr_flags, chattr_mask & CHATTR_EARLY_FL, NULL);
 
         r = copy_bytes_full(fdf, fdt, UINT64_MAX, copy_flags, NULL, NULL, progress_bytes, userdata);
-        if (r < 0) {
-                close(fdt);
-                (void) unlink(to);
-                return r;
-        }
+        if (r < 0)
+                goto fail;
 
         (void) copy_times(fdf, fdt, copy_flags);
         (void) copy_xattr(fdf, fdt);
@@ -1099,12 +1216,31 @@ int copy_file_full(
         if (chattr_mask != 0)
                 (void) chattr_fd(fdt, chattr_flags, chattr_mask & ~CHATTR_EARLY_FL, NULL);
 
-        if (close(fdt) < 0) {
-                unlink_noerrno(to);
-                return -errno;
+        if (copy_flags & (COPY_FSYNC|COPY_FSYNC_FULL)) {
+                if (fsync(fdt) < 0) {
+                        r = -errno;
+                        goto fail;
+                }
+        }
+
+        r = close_nointr(TAKE_FD(fdt)); /* even if this fails, the fd is now invalidated */
+        if (r < 0)
+                goto fail;
+
+        if (copy_flags & COPY_FSYNC_FULL) {
+                r = fsync_parent_at(AT_FDCWD, to);
+                if (r < 0)
+                        goto fail;
         }
 
         return 0;
+
+fail:
+        /* Only unlink if we definitely are the ones who created the file */
+        if (FLAGS_SET(flags, O_EXCL))
+                (void) unlink(to);
+
+        return r;
 }
 
 int copy_file_atomic_full(
@@ -1172,6 +1308,12 @@ int copy_file_atomic_full(
         if (fchmod(fdt, mode) < 0)
                 return -errno;
 
+        if ((copy_flags & (COPY_FSYNC|COPY_FSYNC_FULL))) {
+                /* Sync the file */
+                if (fsync(fdt) < 0)
+                        return -errno;
+        }
+
         if (copy_flags & COPY_REPLACE) {
                 if (renameat(AT_FDCWD, t, AT_FDCWD, to) < 0)
                         return -errno;
@@ -1181,11 +1323,27 @@ int copy_file_atomic_full(
                         return r;
         }
 
+        t = mfree(t);
+
         if (chattr_mask != 0)
                 (void) chattr_fd(fdt, chattr_flags, chattr_mask & ~CHATTR_EARLY_FL, NULL);
 
-        t = mfree(t);
+        r = close_nointr(TAKE_FD(fdt)); /* even if this fails, the fd is now invalidated */
+        if (r < 0)
+                goto fail;
+
+        if (copy_flags & COPY_FSYNC_FULL) {
+                /* Sync the parent directory */
+                r = fsync_parent_at(AT_FDCWD, to);
+                if (r < 0)
+                        goto fail;
+        }
+
         return 0;
+
+fail:
+        (void) unlink(to);
+        return r;
 }
 
 int copy_times(int fdf, int fdt, CopyFlags flags) {
index b36ddfcb0157bfd8ff7482be8834afe987deecac..f8992843e4594f78a52d548d58e8e0c16cfd10b9 100644 (file)
 #include <sys/types.h>
 
 typedef enum CopyFlags {
-        COPY_REFLINK     = 1 << 0, /* Try to reflink */
-        COPY_MERGE       = 1 << 1, /* Merge existing trees with our new one to copy */
-        COPY_REPLACE     = 1 << 2, /* Replace an existing file if there's one */
-        COPY_SAME_MOUNT  = 1 << 3, /* Don't descend recursively into other file systems, across mount point boundaries */
-        COPY_MERGE_EMPTY = 1 << 4, /* Merge an existing, empty directory with our new tree to copy */
-        COPY_CRTIME      = 1 << 5, /* Generate a user.crtime_usec xattr off the source crtime if there is one, on copying */
-        COPY_SIGINT      = 1 << 6, /* Check for SIGINT regularly and return EINTR if seen (caller needs to block SIGINT) */
-        COPY_MAC_CREATE  = 1 << 7, /* Create files with the correct MAC label (currently SELinux only) */
-        COPY_HARDLINKS   = 1 << 8, /* Try to reproduce hard links */
+        COPY_REFLINK     = 1 << 0,  /* Try to reflink */
+        COPY_MERGE       = 1 << 1,  /* Merge existing trees with our new one to copy */
+        COPY_REPLACE     = 1 << 2,  /* Replace an existing file if there's one */
+        COPY_SAME_MOUNT  = 1 << 3,  /* Don't descend recursively into other file systems, across mount point boundaries */
+        COPY_MERGE_EMPTY = 1 << 4,  /* Merge an existing, empty directory with our new tree to copy */
+        COPY_CRTIME      = 1 << 5,  /* Generate a user.crtime_usec xattr off the source crtime if there is one, on copying */
+        COPY_SIGINT      = 1 << 6,  /* Check for SIGINT regularly and return EINTR if seen (caller needs to block SIGINT) */
+        COPY_SIGTERM     = 1 << 7,  /* ditto, but for SIGTERM */
+        COPY_MAC_CREATE  = 1 << 8,  /* Create files with the correct MAC label (currently SELinux only) */
+        COPY_HARDLINKS   = 1 << 9,  /* Try to reproduce hard links */
+        COPY_FSYNC       = 1 << 10, /* fsync() after we are done */
+        COPY_FSYNC_FULL  = 1 << 11, /* fsync_full() after we are done */
+        COPY_SYNCFS      = 1 << 12, /* syncfs() the *top-level* dir after we are done */
 } CopyFlags;
 
 typedef int (*copy_progress_bytes_t)(uint64_t n_bytes, void *userdata);
index 6c2d9dbc76ca59300208f534c1ebd9b49b744d34..3bc5fbef51268b3e379f471c4015a451a5bb5ec1 100644 (file)
@@ -299,6 +299,8 @@ int get_credential_host_secret(CredentialSecretFlags flags, void **ret, size_t *
                         if (ret) {
                                 void *copy;
 
+                                assert(sz <= sizeof(f->data)); /* Ensure we don't read past f->data bounds */
+
                                 copy = memdup(f->data, sz);
                                 if (!copy)
                                         return -ENOMEM;
@@ -369,7 +371,10 @@ struct _packed_ encrypted_credential_header {
 };
 
 struct _packed_ tpm2_credential_header {
-        le64_t pcr_mask;
+        le64_t pcr_mask; /* Note that the spec for PC Clients only mandates 24 PCRs, and that's what systems
+                          * generally have. But keep the door open for more. */
+        le16_t pcr_bank; /* For now, either TPM2_ALG_SHA256 or TPM2_ALG_SHA1 */
+        le16_t _zero;    /* Filler to maintain 32bit alignment */
         le32_t blob_size;
         le32_t policy_hash_size;
         uint8_t policy_hash_and_blob[];
@@ -439,6 +444,7 @@ int encrypt_credential_and_warn(
         struct encrypted_credential_header *h;
         int ksz, bsz, ivsz, tsz, added, r;
         uint8_t md[SHA256_DIGEST_LENGTH];
+        uint16_t tpm2_pcr_bank = 0;
         const EVP_CIPHER *cc;
 #if HAVE_TPM2
         bool try_tpm2 = false;
@@ -505,7 +511,8 @@ int encrypt_credential_and_warn(
                               &tpm2_blob,
                               &tpm2_blob_size,
                               &tpm2_policy_hash,
-                              &tpm2_policy_hash_size);
+                              &tpm2_policy_hash_size,
+                              &tpm2_pcr_bank);
                 if (r < 0) {
                         if (!sd_id128_is_null(with_key))
                                 return r;
@@ -598,6 +605,7 @@ int encrypt_credential_and_warn(
 
                 t = (struct tpm2_credential_header*) ((uint8_t*) output + p);
                 t->pcr_mask = htole64(tpm2_pcr_mask);
+                t->pcr_bank = htole16(tpm2_pcr_bank);
                 t->blob_size = htole32(tpm2_blob_size);
                 t->policy_hash_size = htole32(tpm2_policy_hash_size);
                 memcpy(t->policy_hash_and_blob, tpm2_blob, tpm2_blob_size);
@@ -739,6 +747,10 @@ int decrypt_credential_and_warn(
 
                 if (le64toh(t->pcr_mask) >= (UINT64_C(1) << TPM2_PCRS_MAX))
                         return log_error_errno(SYNTHETIC_ERRNO(EBADMSG), "TPM2 PCR mask out of range.");
+                if (!tpm2_pcr_bank_supported(le16toh(t->pcr_bank)))
+                        return log_error_errno(SYNTHETIC_ERRNO(EBADMSG), "TPM2 PCR bank invalid or not supported");
+                if (le16toh(t->_zero) != 0)
+                        return log_error_errno(SYNTHETIC_ERRNO(EBADMSG), "TPM2 padding space not zero.");
                 if (le32toh(t->blob_size) > CREDENTIAL_FIELD_SIZE_MAX)
                         return log_error_errno(SYNTHETIC_ERRNO(EBADMSG), "Unexpected TPM2 blob size.");
                 if (le32toh(t->policy_hash_size) > CREDENTIAL_FIELD_SIZE_MAX)
@@ -755,6 +767,7 @@ int decrypt_credential_and_warn(
 
                 r = tpm2_unseal(tpm2_device,
                                 le64toh(t->pcr_mask),
+                                le16toh(t->pcr_bank),
                                 t->policy_hash_and_blob,
                                 le32toh(t->blob_size),
                                 t->policy_hash_and_blob + le32toh(t->blob_size),
index 07e29e1019129db9e91fad8b49ec24bf9e1cfba7..9ea89ee9200803f374288f557968ec7d4dd23f8b 100644 (file)
@@ -220,9 +220,11 @@ int devnode_acl_all(const char *seat,
         if (dir) {
                 FOREACH_DIRENT(dent, dir, return -errno) {
                         _cleanup_free_ char *unescaped_devname = NULL;
+                        ssize_t l;
 
-                        if (cunescape(dent->d_name, UNESCAPE_RELAX, &unescaped_devname) < 0)
-                                return -ENOMEM;
+                        l = cunescape(dent->d_name, UNESCAPE_RELAX, &unescaped_devname);
+                        if (l < 0)
+                                return l;
 
                         n = path_join("/dev", unescaped_devname);
                         if (!n)
index 5c833afc788b0c8b15143a7b82caa2cbc4485b68..521264ec29b3b194a8f636fe76157004746b6c5e 100644 (file)
@@ -1208,6 +1208,7 @@ int image_read_metadata(Image *i) {
                                 DISSECT_IMAGE_GENERIC_ROOT |
                                 DISSECT_IMAGE_REQUIRE_ROOT |
                                 DISSECT_IMAGE_RELAX_VAR_CHECK |
+                                DISSECT_IMAGE_READ_ONLY |
                                 DISSECT_IMAGE_USR_NO_ROOT,
                                 &m);
                 if (r < 0)
index c6542cec7022b26a15d714fefaae0a86a01d7b15..27b9ac9569e7674e094b2cbcffc8fc85e15219b3 100644 (file)
@@ -506,12 +506,11 @@ static int device_wait_for_initialization_harder(
         left = usec_sub_unsigned(deadline, start);
 
         if (DEBUG_LOGGING) {
-                char buf[FORMAT_TIMESPAN_MAX];
                 const char *sn = NULL;
 
                 (void) sd_device_get_sysname(device, &sn);
                 log_device_debug(device,
-                                 "Waiting for device '%s' to initialize for %s.", strna(sn), format_timespan(buf, sizeof(buf), left, 0));
+                                 "Waiting for device '%s' to initialize for %s.", strna(sn), FORMAT_TIMESPAN(left, 0));
         }
 
         if (left != USEC_INFINITY)
@@ -538,26 +537,22 @@ static int device_wait_for_initialization_harder(
 
                 r = device_wait_for_initialization(device, subsystem, local_deadline, ret);
                 if (r >= 0 && DEBUG_LOGGING) {
-                        char buf[FORMAT_TIMESPAN_MAX];
                         const char *sn = NULL;
 
                         (void) sd_device_get_sysname(device, &sn);
                         log_device_debug(device,
                                          "Successfully waited for device '%s' to initialize for %s.",
                                          strna(sn),
-                                         format_timespan(buf, sizeof(buf), usec_sub_unsigned(now(CLOCK_MONOTONIC), start), 0));
+                                         FORMAT_TIMESPAN(usec_sub_unsigned(now(CLOCK_MONOTONIC), start), 0));
 
                 }
                 if (r != -ETIMEDOUT || last_try)
                         return r;
 
-                if (DEBUG_LOGGING) {
-                        char buf[FORMAT_TIMESPAN_MAX];
-
+                if (DEBUG_LOGGING)
                         log_device_debug(device,
                                          "Device didn't initialize within %s, assuming lost event. Retriggering device.",
-                                         format_timespan(buf, sizeof(buf), usec_sub_unsigned(now(CLOCK_MONOTONIC), start), 0));
-                }
+                                         FORMAT_TIMESPAN(usec_sub_unsigned(now(CLOCK_MONOTONIC), start), 0));
 
                 r = sd_device_trigger(device, SD_DEVICE_CHANGE);
                 if (r < 0)
@@ -1497,7 +1492,6 @@ static int run_fsck(const char *node, const char *fstype) {
 
 static int fs_grow(const char *node_path, const char *mount_path) {
         _cleanup_close_ int mount_fd = -1, node_fd = -1;
-        char fb[FORMAT_BYTES_MAX];
         uint64_t size, newsize;
         int r;
 
@@ -1519,14 +1513,11 @@ static int fs_grow(const char *node_path, const char *mount_path) {
 
         if (newsize == size)
                 log_debug("Successfully resized \"%s\" to %s bytes.",
-                          mount_path,
-                          format_bytes(fb, sizeof fb, newsize));
+                          mount_path, FORMAT_BYTES(newsize));
         else {
                 assert(newsize < size);
                 log_debug("Successfully resized \"%s\" to %s bytes (%"PRIu64" bytes lost due to blocksize).",
-                          mount_path,
-                          format_bytes(fb, sizeof fb, newsize),
-                          size - newsize);
+                          mount_path, FORMAT_BYTES(newsize), size - newsize);
         }
 
         return 0;
index 031ca4cb4c8f8b9f5aaccb54c2efb332af0b3e0b..cffa3fe96e7644ce63f6a1cec37958f64c523c62 100644 (file)
@@ -448,6 +448,29 @@ ExecCommandFlags exec_command_flags_from_string(const char *s) {
                 return 1 << idx;
 }
 
+_noreturn_ void freeze(void) {
+        log_close();
+
+        /* Make sure nobody waits for us on a socket anymore */
+        (void) close_all_fds_full(NULL, 0, false);
+
+        sync();
+
+        /* Let's not freeze right away, but keep reaping zombies. */
+        for (;;) {
+                int r;
+                siginfo_t si = {};
+
+                r = waitid(P_ALL, 0, &si, WEXITED);
+                if (r < 0 && errno != EINTR)
+                        break;
+        }
+
+        /* waitid() failed with an unexpected error, things are really borked. Freeze now! */
+        for (;;)
+                pause();
+}
+
 int fexecve_or_execve(int executable_fd, const char *executable, char *const argv[], char *const envp[]) {
 #if ENABLE_FEXECVE
         execveat(executable_fd, "", argv, envp, AT_EMPTY_PATH);
@@ -470,3 +493,76 @@ int fexecve_or_execve(int executable_fd, const char *executable, char *const arg
                 execve(executable, argv, envp);
         return -errno;
 }
+
+int fork_agent(const char *name, int except[], size_t n_except, pid_t *ret_pid, const char *path, ...) {
+        bool stdout_is_tty, stderr_is_tty;
+        size_t n, i;
+        va_list ap;
+        char **l;
+        int r;
+
+        assert(path);
+
+        /* Spawns a temporary TTY agent, making sure it goes away when we go away */
+
+        r = safe_fork_full(name,
+                           except,
+                           n_except,
+                           FORK_RESET_SIGNALS|FORK_DEATHSIG|FORK_CLOSE_ALL_FDS|FORK_REOPEN_LOG,
+                           ret_pid);
+        if (r < 0)
+                return r;
+        if (r > 0)
+                return 0;
+
+        /* In the child: */
+
+        stdout_is_tty = isatty(STDOUT_FILENO);
+        stderr_is_tty = isatty(STDERR_FILENO);
+
+        if (!stdout_is_tty || !stderr_is_tty) {
+                int fd;
+
+                /* Detach from stdout/stderr and reopen /dev/tty for them. This is important to ensure that
+                 * when systemctl is started via popen() or a similar call that expects to read EOF we
+                 * actually do generate EOF and not delay this indefinitely by keeping an unused copy of
+                 * stdin around. */
+                fd = open("/dev/tty", O_WRONLY);
+                if (fd < 0) {
+                        log_error_errno(errno, "Failed to open /dev/tty: %m");
+                        _exit(EXIT_FAILURE);
+                }
+
+                if (!stdout_is_tty && dup2(fd, STDOUT_FILENO) < 0) {
+                        log_error_errno(errno, "Failed to dup2 /dev/tty: %m");
+                        _exit(EXIT_FAILURE);
+                }
+
+                if (!stderr_is_tty && dup2(fd, STDERR_FILENO) < 0) {
+                        log_error_errno(errno, "Failed to dup2 /dev/tty: %m");
+                        _exit(EXIT_FAILURE);
+                }
+
+                safe_close_above_stdio(fd);
+        }
+
+        (void) rlimit_nofile_safe();
+
+        /* Count arguments */
+        va_start(ap, path);
+        for (n = 0; va_arg(ap, char*); n++)
+                ;
+        va_end(ap);
+
+        /* Allocate strv */
+        l = newa(char*, n + 1);
+
+        /* Fill in arguments */
+        va_start(ap, path);
+        for (i = 0; i <= n; i++)
+                l[i] = va_arg(ap, char*);
+        va_end(ap);
+
+        execv(path, l);
+        _exit(EXIT_FAILURE);
+}
index 9ce5324de93ad3b6da0b1e5be30df65f3d3b0392..05f8e1af8358bf17094c19e6a8019e9f8362e5c9 100644 (file)
@@ -47,4 +47,8 @@ extern const gather_stdout_callback_t gather_environment[_STDOUT_CONSUME_MAX];
 const char* exec_command_flags_to_string(ExecCommandFlags i);
 ExecCommandFlags exec_command_flags_from_string(const char *s);
 
+_noreturn_ void freeze(void);
+
 int fexecve_or_execve(int executable_fd, const char *executable, char *const argv[], char *const envp[]);
+
+int fork_agent(const char *name, int except[], size_t n_except, pid_t *ret_pid, const char *path, ...) _sentinel_;
index 1c28fa73fa73f81fbbd7e89da1917e243b76f9f3..c2bde30131f45da05bb1b08f85469ae74aaf9596 100644 (file)
@@ -316,7 +316,7 @@ static size_t table_data_size(TableDataType type, const void *data) {
                 return sizeof(mode_t);
 
         default:
-                assert_not_reached("Uh? Unexpected cell type");
+                assert_not_reached();
         }
 }
 
@@ -1048,7 +1048,7 @@ int table_add_many_internal(Table *t, TableDataType first_type, ...) {
                         return 0;
 
                 default:
-                        assert_not_reached("Uh? Unexpected data type.");
+                        assert_not_reached();
                 }
 
                 r = table_add_cell(t, &last_cell, type, data);
@@ -1441,7 +1441,7 @@ static const char *table_data_format(Table *t, TableData *d, bool avoid_uppercas
                 _cleanup_free_ char *p = NULL;
                 char *ret;
 
-                p = new(char, FORMAT_TIMESTAMP_MAX);
+                p = new(char, d->type == TABLE_TIMESTAMP_RELATIVE ? FORMAT_TIMESTAMP_RELATIVE_MAX : FORMAT_TIMESTAMP_MAX);
                 if (!p)
                         return NULL;
 
@@ -1450,7 +1450,7 @@ static const char *table_data_format(Table *t, TableData *d, bool avoid_uppercas
                 else if (d->type == TABLE_TIMESTAMP_UTC)
                         ret = format_timestamp_style(p, FORMAT_TIMESTAMP_MAX, d->timestamp, TIMESTAMP_UTC);
                 else
-                        ret = format_timestamp_relative(p, FORMAT_TIMESTAMP_MAX, d->timestamp);
+                        ret = format_timestamp_relative(p, FORMAT_TIMESTAMP_RELATIVE_MAX, d->timestamp);
                 if (!ret)
                         return "n/a";
 
@@ -1763,7 +1763,7 @@ static const char *table_data_format(Table *t, TableData *d, bool avoid_uppercas
         }
 
         case TABLE_MODE: {
-                _cleanup_free_ char *p;
+                _cleanup_free_ char *p = NULL;
 
                 if (d->mode == MODE_INVALID)
                         return "n/a";
@@ -1778,7 +1778,7 @@ static const char *table_data_format(Table *t, TableData *d, bool avoid_uppercas
         }
 
         default:
-                assert_not_reached("Unexpected type?");
+                assert_not_reached();
         }
 
         return d->formatted;
index 882d11ca6c482c4dae3b62c31ce1bbfdcf23eb16..edd56c1493a4f0274ee08c2253e3617a8619933a 100644 (file)
@@ -5,59 +5,63 @@
 #include "utf8.h"
 
 const GptPartitionType gpt_partition_type_table[] = {
-        { GPT_ROOT_X86,              "root-x86"              },
-        { GPT_ROOT_X86_VERITY,       "root-x86-verity"       },
-        { GPT_ROOT_X86_64,           "root-x86-64"           },
-        { GPT_ROOT_X86_64_VERITY,    "root-x86-64-verity"    },
-        { GPT_ROOT_ARM,              "root-arm"              },
-        { GPT_ROOT_ARM_VERITY,       "root-arm-verity"       },
-        { GPT_ROOT_ARM_64,           "root-arm64"            },
-        { GPT_ROOT_ARM_64_VERITY,    "root-arm64-verity"     },
-        { GPT_ROOT_IA64,             "root-ia64"             },
-        { GPT_ROOT_IA64_VERITY,      "root-ia64-verity"      },
-        { GPT_ROOT_RISCV32,          "root-riscv32"          },
-        { GPT_ROOT_RISCV32_VERITY,   "root-riscv32-verity"   },
-        { GPT_ROOT_RISCV64,          "root-riscv64"          },
-        { GPT_ROOT_RISCV64_VERITY,   "root-riscv64-verity"   },
+        { GPT_ROOT_X86,                "root-x86"                },
+        { GPT_ROOT_X86_VERITY,         "root-x86-verity"         },
+        { GPT_ROOT_X86_64,             "root-x86-64"             },
+        { GPT_ROOT_X86_64_VERITY,      "root-x86-64-verity"      },
+        { GPT_ROOT_ARM,                "root-arm"                },
+        { GPT_ROOT_ARM_VERITY,         "root-arm-verity"         },
+        { GPT_ROOT_ARM_64,             "root-arm64"              },
+        { GPT_ROOT_ARM_64_VERITY,      "root-arm64-verity"       },
+        { GPT_ROOT_IA64,               "root-ia64"               },
+        { GPT_ROOT_IA64_VERITY,        "root-ia64-verity"        },
+        { GPT_ROOT_LOONGARCH64,        "root-loongarch64"        },
+        { GPT_ROOT_LOONGARCH64_VERITY, "root-loongarch64-verity" },
+        { GPT_ROOT_RISCV32,            "root-riscv32"            },
+        { GPT_ROOT_RISCV32_VERITY,     "root-riscv32-verity"     },
+        { GPT_ROOT_RISCV64,            "root-riscv64"            },
+        { GPT_ROOT_RISCV64_VERITY,     "root-riscv64-verity"     },
 #ifdef GPT_ROOT_NATIVE
-        { GPT_ROOT_NATIVE,           "root"                  },
-        { GPT_ROOT_NATIVE_VERITY,    "root-verity"           },
+        { GPT_ROOT_NATIVE,             "root"                    },
+        { GPT_ROOT_NATIVE_VERITY,      "root-verity"             },
 #endif
 #ifdef GPT_ROOT_SECONDARY
-        { GPT_ROOT_SECONDARY,        "root-secondary"        },
-        { GPT_ROOT_SECONDARY_VERITY, "root-secondary-verity" },
+        { GPT_ROOT_SECONDARY,          "root-secondary"          },
+        { GPT_ROOT_SECONDARY_VERITY,   "root-secondary-verity"   },
 #endif
-        { GPT_USR_X86,               "usr-x86"               },
-        { GPT_USR_X86_VERITY,        "usr-x86-verity"        },
-        { GPT_USR_X86_64,            "usr-x86-64"            },
-        { GPT_USR_X86_64_VERITY,     "usr-x86-64-verity"     },
-        { GPT_USR_ARM,               "usr-arm"               },
-        { GPT_USR_ARM_VERITY,        "usr-arm-verity"        },
-        { GPT_USR_ARM_64,            "usr-arm64"             },
-        { GPT_USR_ARM_64_VERITY,     "usr-arm64-verity"      },
-        { GPT_USR_IA64,              "usr-ia64"              },
-        { GPT_USR_IA64_VERITY,       "usr-ia64-verity"       },
-        { GPT_USR_RISCV32,           "usr-riscv32"           },
-        { GPT_USR_RISCV32_VERITY,    "usr-riscv32-verity"    },
-        { GPT_USR_RISCV64,           "usr-riscv64"           },
-        { GPT_USR_RISCV64_VERITY,    "usr-riscv64-verity"    },
+        { GPT_USR_X86,                 "usr-x86"                 },
+        { GPT_USR_X86_VERITY,          "usr-x86-verity"          },
+        { GPT_USR_X86_64,              "usr-x86-64"              },
+        { GPT_USR_X86_64_VERITY,       "usr-x86-64-verity"       },
+        { GPT_USR_ARM,                 "usr-arm"                 },
+        { GPT_USR_ARM_VERITY,          "usr-arm-verity"          },
+        { GPT_USR_ARM_64,              "usr-arm64"               },
+        { GPT_USR_ARM_64_VERITY,       "usr-arm64-verity"        },
+        { GPT_USR_IA64,                "usr-ia64"                },
+        { GPT_USR_IA64_VERITY,         "usr-ia64-verity"         },
+        { GPT_USR_LOONGARCH64,         "usr-loongarch64"         },
+        { GPT_USR_LOONGARCH64_VERITY,  "usr-loongarch64-verity"  },
+        { GPT_USR_RISCV32,             "usr-riscv32"             },
+        { GPT_USR_RISCV32_VERITY,      "usr-riscv32-verity"      },
+        { GPT_USR_RISCV64,             "usr-riscv64"             },
+        { GPT_USR_RISCV64_VERITY,      "usr-riscv64-verity"      },
 #ifdef GPT_USR_NATIVE
-        { GPT_USR_NATIVE,            "usr"                   },
-        { GPT_USR_NATIVE_VERITY,     "usr-verity"            },
+        { GPT_USR_NATIVE,              "usr"                     },
+        { GPT_USR_NATIVE_VERITY,       "usr-verity"              },
 #endif
 #ifdef GPT_USR_SECONDARY
-        { GPT_USR_SECONDARY,         "usr-secondary"         },
-        { GPT_USR_SECONDARY_VERITY,  "usr-secondary-verity"  },
+        { GPT_USR_SECONDARY,           "usr-secondary"           },
+        { GPT_USR_SECONDARY_VERITY,    "usr-secondary-verity"    },
 #endif
-        { GPT_ESP,                   "esp"                   },
-        { GPT_XBOOTLDR,              "xbootldr"              },
-        { GPT_SWAP,                  "swap"                  },
-        { GPT_HOME,                  "home"                  },
-        { GPT_SRV,                   "srv"                   },
-        { GPT_VAR,                   "var"                   },
-        { GPT_TMP,                   "tmp"                   },
-        { GPT_USER_HOME,             "user-home"             },
-        { GPT_LINUX_GENERIC,         "linux-generic"         },
+        { GPT_ESP,                     "esp"                     },
+        { GPT_XBOOTLDR,                "xbootldr"                },
+        { GPT_SWAP,                    "swap"                    },
+        { GPT_HOME,                    "home"                    },
+        { GPT_SRV,                     "srv"                     },
+        { GPT_VAR,                     "var"                     },
+        { GPT_TMP,                     "tmp"                     },
+        { GPT_USER_HOME,               "user-home"               },
+        { GPT_LINUX_GENERIC,           "linux-generic"           },
         {}
 };
 
@@ -114,6 +118,7 @@ bool gpt_partition_type_is_root(sd_id128_t id) {
                                GPT_ROOT_ARM,
                                GPT_ROOT_ARM_64,
                                GPT_ROOT_IA64,
+                               GPT_ROOT_LOONGARCH64,
                                GPT_ROOT_RISCV32,
                                GPT_ROOT_RISCV64);
 }
@@ -125,6 +130,7 @@ bool gpt_partition_type_is_root_verity(sd_id128_t id) {
                                GPT_ROOT_ARM_VERITY,
                                GPT_ROOT_ARM_64_VERITY,
                                GPT_ROOT_IA64_VERITY,
+                               GPT_ROOT_LOONGARCH64_VERITY,
                                GPT_ROOT_RISCV32_VERITY,
                                GPT_ROOT_RISCV64_VERITY);
 }
@@ -136,6 +142,7 @@ bool gpt_partition_type_is_usr(sd_id128_t id) {
                                GPT_USR_ARM,
                                GPT_USR_ARM_64,
                                GPT_USR_IA64,
+                               GPT_USR_LOONGARCH64,
                                GPT_USR_RISCV32,
                                GPT_USR_RISCV64);
 }
@@ -147,6 +154,7 @@ bool gpt_partition_type_is_usr_verity(sd_id128_t id) {
                                GPT_USR_ARM_VERITY,
                                GPT_USR_ARM_64_VERITY,
                                GPT_USR_IA64_VERITY,
+                               GPT_USR_LOONGARCH64_VERITY,
                                GPT_USR_RISCV32_VERITY,
                                GPT_USR_RISCV64_VERITY);
 }
index dc530ef1b02f97f8a231d74fa1ce99ea71762c1b..a5fc9534e1efd14252f857febf89b92c825c4fc7 100644 (file)
@@ -7,49 +7,54 @@
 
 #include "id128-util.h"
 
-/* We only support root disk discovery for x86, x86-64, Itanium and ARM for now, since EFI for anything else
- * doesn't really exist, and we only care for root partitions on the same disk as the EFI ESP. */
-
-#define GPT_ROOT_X86      SD_ID128_MAKE(44,47,95,40,f2,97,41,b2,9a,f7,d1,31,d5,f0,45,8a)
-#define GPT_ROOT_X86_64   SD_ID128_MAKE(4f,68,bc,e3,e8,cd,4d,b1,96,e7,fb,ca,f9,84,b7,09)
-#define GPT_ROOT_ARM      SD_ID128_MAKE(69,da,d7,10,2c,e4,4e,3c,b1,6c,21,a1,d4,9a,be,d3)
-#define GPT_ROOT_ARM_64   SD_ID128_MAKE(b9,21,b0,45,1d,f0,41,c3,af,44,4c,6f,28,0d,3f,ae)
-#define GPT_ROOT_IA64     SD_ID128_MAKE(99,3d,8d,3d,f8,0e,42,25,85,5a,9d,af,8e,d7,ea,97)
-#define GPT_ROOT_RISCV32  SD_ID128_MAKE(60,d5,a7,fe,8e,7d,43,5c,b7,14,3d,d8,16,21,44,e1)
-#define GPT_ROOT_RISCV64  SD_ID128_MAKE(72,ec,70,a6,cf,74,40,e6,bd,49,4b,da,08,e8,f2,24)
-#define GPT_USR_X86       SD_ID128_MAKE(75,25,0d,76,8c,c6,45,8e,bd,66,bd,47,cc,81,a8,12)
-#define GPT_USR_X86_64    SD_ID128_MAKE(84,84,68,0c,95,21,48,c6,9c,11,b0,72,06,56,f6,9e)
-#define GPT_USR_ARM       SD_ID128_MAKE(7d,03,59,a3,02,b3,4f,0a,86,5c,65,44,03,e7,06,25)
-#define GPT_USR_ARM_64    SD_ID128_MAKE(b0,e0,10,50,ee,5f,43,90,94,9a,91,01,b1,71,04,e9)
-#define GPT_USR_IA64      SD_ID128_MAKE(43,01,d2,a6,4e,3b,4b,2a,bb,94,9e,0b,2c,42,25,ea)
-#define GPT_USR_RISCV32   SD_ID128_MAKE(b9,33,fb,22,5c,3f,4f,91,af,90,e2,bb,0f,a5,07,02)
-#define GPT_USR_RISCV64   SD_ID128_MAKE(be,ae,c3,4b,84,42,43,9b,a4,0b,98,43,81,ed,09,7d)
-#define GPT_ESP           SD_ID128_MAKE(c1,2a,73,28,f8,1f,11,d2,ba,4b,00,a0,c9,3e,c9,3b)
-#define GPT_XBOOTLDR      SD_ID128_MAKE(bc,13,c2,ff,59,e6,42,62,a3,52,b2,75,fd,6f,71,72)
-#define GPT_SWAP          SD_ID128_MAKE(06,57,fd,6d,a4,ab,43,c4,84,e5,09,33,c8,4b,4f,4f)
-#define GPT_HOME          SD_ID128_MAKE(93,3a,c7,e1,2e,b4,4f,13,b8,44,0e,14,e2,ae,f9,15)
-#define GPT_SRV           SD_ID128_MAKE(3b,8f,84,25,20,e0,4f,3b,90,7f,1a,25,a7,6f,98,e8)
-#define GPT_VAR           SD_ID128_MAKE(4d,21,b0,16,b5,34,45,c2,a9,fb,5c,16,e0,91,fd,2d)
-#define GPT_TMP           SD_ID128_MAKE(7e,c6,f5,57,3b,c5,4a,ca,b2,93,16,ef,5d,f6,39,d1)
-#define GPT_USER_HOME     SD_ID128_MAKE(77,3f,91,ef,66,d4,49,b5,bd,83,d6,83,bf,40,ad,16)
-#define GPT_LINUX_GENERIC SD_ID128_MAKE(0f,c6,3d,af,84,83,47,72,8e,79,3d,69,d8,47,7d,e4)
+/* We only support root disk discovery for x86, x86-64, Itanium, ARM and LoongArch for now,
+ * since EFI for anything else doesn't really exist, and we only care for root partitions
+ * on the same disk as the EFI ESP. */
+
+#define GPT_ROOT_X86         SD_ID128_MAKE(44,47,95,40,f2,97,41,b2,9a,f7,d1,31,d5,f0,45,8a)
+#define GPT_ROOT_X86_64      SD_ID128_MAKE(4f,68,bc,e3,e8,cd,4d,b1,96,e7,fb,ca,f9,84,b7,09)
+#define GPT_ROOT_ARM         SD_ID128_MAKE(69,da,d7,10,2c,e4,4e,3c,b1,6c,21,a1,d4,9a,be,d3)
+#define GPT_ROOT_ARM_64      SD_ID128_MAKE(b9,21,b0,45,1d,f0,41,c3,af,44,4c,6f,28,0d,3f,ae)
+#define GPT_ROOT_IA64        SD_ID128_MAKE(99,3d,8d,3d,f8,0e,42,25,85,5a,9d,af,8e,d7,ea,97)
+#define GPT_ROOT_LOONGARCH64 SD_ID128_MAKE(77,05,58,00,79,2c,4f,94,b3,9a,99,c9,1b,76,2b,b6)
+#define GPT_ROOT_RISCV32     SD_ID128_MAKE(60,d5,a7,fe,8e,7d,43,5c,b7,14,3d,d8,16,21,44,e1)
+#define GPT_ROOT_RISCV64     SD_ID128_MAKE(72,ec,70,a6,cf,74,40,e6,bd,49,4b,da,08,e8,f2,24)
+#define GPT_USR_X86          SD_ID128_MAKE(75,25,0d,76,8c,c6,45,8e,bd,66,bd,47,cc,81,a8,12)
+#define GPT_USR_X86_64       SD_ID128_MAKE(84,84,68,0c,95,21,48,c6,9c,11,b0,72,06,56,f6,9e)
+#define GPT_USR_ARM          SD_ID128_MAKE(7d,03,59,a3,02,b3,4f,0a,86,5c,65,44,03,e7,06,25)
+#define GPT_USR_ARM_64       SD_ID128_MAKE(b0,e0,10,50,ee,5f,43,90,94,9a,91,01,b1,71,04,e9)
+#define GPT_USR_IA64         SD_ID128_MAKE(43,01,d2,a6,4e,3b,4b,2a,bb,94,9e,0b,2c,42,25,ea)
+#define GPT_USR_LOONGARCH64  SD_ID128_MAKE(e6,11,c7,02,57,5c,4c,be,9a,46,43,4f,a0,bf,7e,3f)
+#define GPT_USR_RISCV32      SD_ID128_MAKE(b9,33,fb,22,5c,3f,4f,91,af,90,e2,bb,0f,a5,07,02)
+#define GPT_USR_RISCV64      SD_ID128_MAKE(be,ae,c3,4b,84,42,43,9b,a4,0b,98,43,81,ed,09,7d)
+#define GPT_ESP              SD_ID128_MAKE(c1,2a,73,28,f8,1f,11,d2,ba,4b,00,a0,c9,3e,c9,3b)
+#define GPT_XBOOTLDR         SD_ID128_MAKE(bc,13,c2,ff,59,e6,42,62,a3,52,b2,75,fd,6f,71,72)
+#define GPT_SWAP             SD_ID128_MAKE(06,57,fd,6d,a4,ab,43,c4,84,e5,09,33,c8,4b,4f,4f)
+#define GPT_HOME             SD_ID128_MAKE(93,3a,c7,e1,2e,b4,4f,13,b8,44,0e,14,e2,ae,f9,15)
+#define GPT_SRV              SD_ID128_MAKE(3b,8f,84,25,20,e0,4f,3b,90,7f,1a,25,a7,6f,98,e8)
+#define GPT_VAR              SD_ID128_MAKE(4d,21,b0,16,b5,34,45,c2,a9,fb,5c,16,e0,91,fd,2d)
+#define GPT_TMP              SD_ID128_MAKE(7e,c6,f5,57,3b,c5,4a,ca,b2,93,16,ef,5d,f6,39,d1)
+#define GPT_USER_HOME        SD_ID128_MAKE(77,3f,91,ef,66,d4,49,b5,bd,83,d6,83,bf,40,ad,16)
+#define GPT_LINUX_GENERIC    SD_ID128_MAKE(0f,c6,3d,af,84,83,47,72,8e,79,3d,69,d8,47,7d,e4)
 
 /* Verity partitions for the root partitions above (we only define them for the root and /usr partitions,
  * because only they are commonly read-only and hence suitable for verity). */
-#define GPT_ROOT_X86_VERITY    SD_ID128_MAKE(d1,3c,5d,3b,b5,d1,42,2a,b2,9f,94,54,fd,c8,9d,76)
-#define GPT_ROOT_X86_64_VERITY SD_ID128_MAKE(2c,73,57,ed,eb,d2,46,d9,ae,c1,23,d4,37,ec,2b,f5)
-#define GPT_ROOT_ARM_VERITY    SD_ID128_MAKE(73,86,cd,f2,20,3c,47,a9,a4,98,f2,ec,ce,45,a2,d6)
-#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)
-#define GPT_ROOT_RISCV32_VERITY SD_ID128_MAKE(ae,02,53,be,11,67,40,07,ac,68,43,92,6c,14,c5,de)
-#define GPT_ROOT_RISCV64_VERITY SD_ID128_MAKE(b6,ed,55,82,44,0b,42,09,b8,da,5f,f7,c4,19,ea,3d)
-#define GPT_USR_X86_VERITY     SD_ID128_MAKE(8f,46,1b,0d,14,ee,4e,81,9a,a9,04,9b,6f,b9,7a,bd)
-#define GPT_USR_X86_64_VERITY  SD_ID128_MAKE(77,ff,5f,63,e7,b6,46,33,ac,f4,15,65,b8,64,c0,e6)
-#define GPT_USR_ARM_VERITY     SD_ID128_MAKE(c2,15,d7,51,7b,cd,46,49,be,90,66,27,49,0a,4c,05)
-#define GPT_USR_ARM_64_VERITY  SD_ID128_MAKE(6e,11,a4,e7,fb,ca,4d,ed,b9,e9,e1,a5,12,bb,66,4e)
-#define GPT_USR_IA64_VERITY    SD_ID128_MAKE(6a,49,1e,03,3b,e7,45,45,8e,38,83,32,0e,0e,a8,80)
-#define GPT_USR_RISCV32_VERITY SD_ID128_MAKE(cb,1e,e4,e3,8c,d0,41,36,a0,a4,aa,61,a3,2e,87,30)
-#define GPT_USR_RISCV64_VERITY SD_ID128_MAKE(8f,10,56,be,9b,05,47,c4,81,d6,be,53,12,8e,5b,54)
+#define GPT_ROOT_X86_VERITY         SD_ID128_MAKE(d1,3c,5d,3b,b5,d1,42,2a,b2,9f,94,54,fd,c8,9d,76)
+#define GPT_ROOT_X86_64_VERITY      SD_ID128_MAKE(2c,73,57,ed,eb,d2,46,d9,ae,c1,23,d4,37,ec,2b,f5)
+#define GPT_ROOT_ARM_VERITY         SD_ID128_MAKE(73,86,cd,f2,20,3c,47,a9,a4,98,f2,ec,ce,45,a2,d6)
+#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)
+#define GPT_ROOT_LOONGARCH64_VERITY SD_ID128_MAKE(f3,39,3b,22,e9,af,46,13,a9,48,9d,3b,fb,d0,c5,35)
+#define GPT_ROOT_RISCV32_VERITY     SD_ID128_MAKE(ae,02,53,be,11,67,40,07,ac,68,43,92,6c,14,c5,de)
+#define GPT_ROOT_RISCV64_VERITY     SD_ID128_MAKE(b6,ed,55,82,44,0b,42,09,b8,da,5f,f7,c4,19,ea,3d)
+#define GPT_USR_X86_VERITY          SD_ID128_MAKE(8f,46,1b,0d,14,ee,4e,81,9a,a9,04,9b,6f,b9,7a,bd)
+#define GPT_USR_X86_64_VERITY       SD_ID128_MAKE(77,ff,5f,63,e7,b6,46,33,ac,f4,15,65,b8,64,c0,e6)
+#define GPT_USR_ARM_VERITY          SD_ID128_MAKE(c2,15,d7,51,7b,cd,46,49,be,90,66,27,49,0a,4c,05)
+#define GPT_USR_ARM_64_VERITY       SD_ID128_MAKE(6e,11,a4,e7,fb,ca,4d,ed,b9,e9,e1,a5,12,bb,66,4e)
+#define GPT_USR_IA64_VERITY         SD_ID128_MAKE(6a,49,1e,03,3b,e7,45,45,8e,38,83,32,0e,0e,a8,80)
+#define GPT_USR_LOONGARCH64_VERITY  SD_ID128_MAKE(f4,6b,2c,26,59,ae,48,f0,91,06,c5,0e,d4,7f,67,3d)
+#define GPT_USR_RISCV32_VERITY      SD_ID128_MAKE(cb,1e,e4,e3,8c,d0,41,36,a0,a4,aa,61,a3,2e,87,30)
+#define GPT_USR_RISCV64_VERITY      SD_ID128_MAKE(8f,10,56,be,9b,05,47,c4,81,d6,be,53,12,8e,5b,54)
 
 #if defined(__x86_64__)
 #  define GPT_ROOT_NATIVE GPT_ROOT_X86_64
 #  define GPT_USR_NATIVE_VERITY GPT_USR_ARM_VERITY
 #endif
 
+#if defined(__loongarch64)
+#  define GPT_ROOT_NATIVE GPT_ROOT_LOONGARCH64
+#  define GPT_ROOT_NATIVE_VERITY GPT_ROOT_LOONGARCH64_VERITY
+#  define GPT_USR_NATIVE GPT_USR_LOONGARCH64
+#  define GPT_USR_NATIVE_VERITY GPT_USR_LOONGARCH64_VERITY
+#endif
+
 #if defined(__riscv)
 #if (__riscv_xlen == 32)
 #  define GPT_ROOT_NATIVE GPT_ROOT_RISCV32
index 2a30e40686f4d58b1d2dfc1bf9aaaa20cda5b671..bb1e5136a736289d34ea3cc06d2b9a3504e763ed 100644 (file)
 #include "string-table.h"
 #include "string-util.h"
 
-int import_url_last_component(const char *url, char **ret) {
-        const char *e, *p;
-        char *s;
+static const char *skip_protocol_and_hostname(const char *url) {
+        const char *d;
+        size_t n;
+
+        /* A very very lenient implementation of RFC3986 Section 3.2 */
+
+        /* Find colon separating protocol and hostname */
+        d = strchr(url, ':');
+        if (!d || url == d)
+                return NULL;
+        d++;
+
+        /* Skip slashes after colon */
+        d += strspn(d, "/");
+
+        /* Skip everything till next slash or end */
+        n = strcspn(d, "/?#");
+        if (n == 0)
+                return NULL;
+
+        return d + n;
+}
 
-        e = strchrnul(url, '?');
+int import_url_last_component(
+                const char *url,
+                char **ret) {
 
-        while (e > url && e[-1] == '/')
+        const char *e, *p, *h;
+
+        /* This extracts the last path component of the specified URI, i.e. the last non-empty substrings
+         * between two "/" characters. This ignores "Query" and "Fragment" suffixes (as per RFC3986). */
+
+        h = skip_protocol_and_hostname(url);
+        if (!h)
+                return -EINVAL;
+
+        e = h + strcspn(h, "?#"); /* Cut off "Query" and "Fragment" */
+
+        while (e > h && e[-1] == '/') /* Eat trailing slashes */
                 e--;
 
         p = e;
-        while (p > url && p[-1] != '/')
+        while (p > h && p[-1] != '/') /* Find component before that */
                 p--;
 
-        if (e <= p)
-                return -EINVAL;
+        if (e <= p) /* Empty component? */
+                return -EADDRNOTAVAIL;
 
-        s = strndup(p, e - p);
-        if (!s)
-                return -ENOMEM;
+        if (ret) {
+                char *s;
+
+                s = strndup(p, e - p);
+                if (!s)
+                        return -ENOMEM;
+
+                *ret = s;
+        }
 
-        *ret = s;
         return 0;
 }
 
-int import_url_change_last_component(const char *url, const char *suffix, char **ret) {
-        const char *e;
+int import_url_change_suffix(
+                const char *url,
+                size_t n_drop_components,
+                const char *suffix,
+                char **ret) {
+
+        const char *e, *h;
         char *s;
 
         assert(url);
         assert(ret);
 
-        e = strchrnul(url, '?');
+        /* This drops the specified number of path components of the specified URI, i.e. the specified number
+         * of non-empty substring between two "/" characters from the end of the string, and then append the
+         * specified suffix instead. Before doing all this it chops off the "Query" and "Fragment" suffixes
+         * (they are *not* readded to the final URL). Note that n_drop_components may be 0 (in which case the
+         * component are simply added to the end). The suffix may be specified as NULL or empty string in
+         * which case nothing is appended, only the specified number of components chopped off. Note that the
+         * function may be called with n_drop_components == 0 and suffix == NULL, in which case the "Query"
+         * and "Fragment" is chopped off, and ensured the URL ends in a single "/", and that's it. */
+
+        h = skip_protocol_and_hostname(url);
+        if (!h)
+                return -EINVAL;
 
-        while (e > url && e[-1] == '/')
-                e--;
+        e = h + strcspn(h, "?#"); /* Cut off "Query" and "Fragment" */
 
-        while (e > url && e[-1] != '/')
+        while (e > h && e[-1] == '/') /* Eat trailing slashes */
                 e--;
 
-        if (e <= url)
-                return -EINVAL;
+        /* Drop the specified number of components from the end. Note that this is pretty lenient: if there
+         * are less component we silently drop those and then append the suffix to the top. */
+        while (n_drop_components > 0) {
+                while (e > h && e[-1] != '/') /* Eat last word (we don't mind if empty) */
+                        e--;
+
+                while (e > h && e[-1] == '/') /* Eat slashes before the last word */
+                        e--;
+
+                n_drop_components--;
+        }
 
-        s = new(char, (e - url) + strlen(suffix) + 1);
+        s = new(char, (e - url) + 1 + strlen_ptr(suffix) + 1);
         if (!s)
                 return -ENOMEM;
 
-        strcpy(mempcpy(s, url, e - url), suffix);
+        strcpy(stpcpy(mempcpy(s, url, e - url), "/"), strempty(suffix));
         *ret = s;
         return 0;
 }
index c7ec3b4eabda71281acf80d0ef76cc4fff7ec904..3b2425b916537cdb499375844c0aff39fab61e7a 100644 (file)
@@ -14,7 +14,16 @@ typedef enum ImportVerify {
 } ImportVerify;
 
 int import_url_last_component(const char *url, char **ret);
-int import_url_change_last_component(const char *url, const char *suffix, char **ret);
+
+int import_url_change_suffix(const char *url, size_t n_drop_components, const char *suffix, char **ret);
+
+static inline int import_url_change_last_component(const char *url, const char *suffix, char **ret) {
+        return import_url_change_suffix(url, 1, suffix, ret);
+}
+
+static inline int import_url_append_component(const char *url, const char *suffix, char **ret) {
+        return import_url_change_suffix(url, 0, suffix, ret);
+}
 
 const char* import_verify_to_string(ImportVerify v) _const_;
 ImportVerify import_verify_from_string(const char *s) _pure_;
index 4bf868f8e9e193706649233edac6d37368d049d1..a348f0c5728c1c4c2a5f7d3a8f363d9919ecc354 100644 (file)
@@ -2897,7 +2897,7 @@ int unit_file_lookup_state(
                 break;
 
         default:
-                assert_not_reached("Unexpected unit file type.");
+                assert_not_reached();
         }
 
         *ret = state;
@@ -2989,7 +2989,7 @@ static int presets_find_config(UnitFileScope scope, const char *root_dir, char *
         else if (IN_SET(scope, UNIT_FILE_GLOBAL, UNIT_FILE_USER))
                 dirs = user_dirs;
         else
-                assert_not_reached("Invalid unit file scope");
+                assert_not_reached();
 
         return conf_files_list_strv(files, ".preset", root_dir, 0, dirs);
 }
@@ -3173,7 +3173,7 @@ static int query_presets(const char *name, const UnitFilePresets *presets, char
                 log_debug("Preset files say disable %s.", name);
                 return 0;
         default:
-                assert_not_reached("invalid preset action");
+                assert_not_reached();
         }
 }
 
index 9e11dc09c1cc190db729d16313f6007515a96ddd..bbb152481ec42f9eca0a63d38d13d82f734d94e4 100644 (file)
@@ -417,7 +417,7 @@ int journal_importer_process_data(JournalImporter *imp) {
 
                 return 0; /* continue */
         default:
-                assert_not_reached("wtf?");
+                assert_not_reached();
         }
 }
 
index c52460a3ecea9c7c143524ef773f22be53b5e755..ea37728dc52013283a73ba06b14be413c37f51b3 100644 (file)
@@ -505,7 +505,7 @@ static void json_variant_set(JsonVariant *a, JsonVariant *b) {
                 break;
 
         default:
-                assert_not_reached("Unexpected variant type");
+                assert_not_reached();
         }
 }
 
@@ -763,7 +763,7 @@ static size_t json_variant_size(JsonVariant* v) {
                 return offsetof(JsonVariant, value);
 
         default:
-                assert_not_reached("unexpected type");
+                assert_not_reached();
         }
 }
 
@@ -1397,7 +1397,7 @@ bool json_variant_equal(JsonVariant *a, JsonVariant *b) {
         }
 
         default:
-                assert_not_reached("Unknown variant type.");
+                assert_not_reached();
         }
 }
 
@@ -1749,7 +1749,7 @@ static int json_format(FILE *f, JsonVariant *v, JsonFormatFlags flags, const cha
         }
 
         default:
-                assert_not_reached("Unexpected variant type.");
+                assert_not_reached();
         }
 
         return 0;
@@ -2787,7 +2787,7 @@ int json_tokenize(
                 return -EINVAL;
 
         default:
-                assert_not_reached("Unexpected tokenizer state");
+                assert_not_reached();
         }
 
 null_return:
@@ -3156,7 +3156,7 @@ static int json_parse_internal(
                         break;
 
                 default:
-                        assert_not_reached("Unexpected token");
+                        assert_not_reached();
                 }
 
                 if (add) {
index d9fcfc21a9caadf8d89851de25e78d0ce1013d97..869955a58f6c1fa47978c03d411ff8b3ea1e9484 100644 (file)
@@ -17,6 +17,7 @@
 #include "parse-util.h"
 #include "process-util.h"
 #include "set.h"
+#include "stdio-util.h"
 #include "string-util.h"
 #include "terminal-util.h"
 #include "util.h"
@@ -83,14 +84,13 @@ static void log_children_no_yet_killed(Set *pids) {
 
         SET_FOREACH(p, pids) {
                 _cleanup_free_ char *s = NULL;
+                char fallback[DECIMAL_STR_MAX(pid_t)];
 
                 if (get_process_comm(PTR_TO_PID(p), &s) < 0)
-                        (void) asprintf(&s, PID_FMT, PTR_TO_PID(p));
+                        xsprintf(fallback, PID_FMT, PTR_TO_PID(p));
 
-                if (!strextend(&lst_child, ", ", s)) {
-                        log_oom();
-                        return;
-                }
+                if (!strextend(&lst_child, ", ", s ?: fallback))
+                        return (void) log_oom();
         }
 
         if (isempty(lst_child))
index bd69e946f55f9816078b4fa5bb7e9dd1d06adccb..d1f6b5df0396385ee0ec87a1404d0e768a0d6b24 100644 (file)
@@ -422,7 +422,7 @@ int local_outbounds(
                         break;
 
                 default:
-                        assert_not_reached("Unexpected protocol");
+                        assert_not_reached();
                 }
 
                 /* So ideally we'd just use IP_UNICAST_IF here to pass the ifindex info to the kernel before
@@ -493,7 +493,7 @@ int local_outbounds(
                         break;
 
                 default:
-                        assert_not_reached("Unexpected protocol");
+                        assert_not_reached();
                 }
         }
 
index e63c59bd94e324b686a42b1d6986a941ac0c677f..afce8e8fe36393552a35cab14c16cdfa3a0091ba 100644 (file)
@@ -416,7 +416,7 @@ static int output_timestamp_realtime(FILE *f, sd_journal *j, OutputMode mode, Ou
                         break;
 
                 default:
-                        assert_not_reached("Unknown time format");
+                        assert_not_reached();
                 }
         }
 
@@ -579,10 +579,9 @@ static int output_short(
                 }
         }
 
-        if (!(flags & OUTPUT_SHOW_ALL) && !utf8_is_printable(message, message_len)) {
-                char bytes[FORMAT_BYTES_MAX];
-                fprintf(f, "[%s blob data]\n", format_bytes(bytes, sizeof(bytes), message_len));
-        } else {
+        if (!(flags & OUTPUT_SHOW_ALL) && !utf8_is_printable(message, message_len))
+                fprintf(f, "[%s blob data]\n", FORMAT_BYTES(message_len));
+        else {
 
                 /* URLify config_file string in message, if the message starts with it.
                  * Skip URLification if the highlighted pattern overlaps. */
@@ -726,16 +725,13 @@ static int output_verbose(
                                         p, valuelen,
                                         NULL);
                         fputs(off, f);
-                } else {
-                        char bytes[FORMAT_BYTES_MAX];
-
+                } else
                         fprintf(f, "    %s%.*s=[%s blob data]%s\n",
                                 on,
                                 (int) (c - (const char*) data),
                                 (const char*) data,
-                                format_bytes(bytes, sizeof(bytes), length - (c - (const char *) data) - 1),
+                                FORMAT_BYTES(length - (c - (const char *) data) - 1),
                                 off);
-                }
         }
 
         if (r < 0)
index ef3527e9a7f68b035e9277d4c00795111be2c515..3b309828351c5ab541d766b1cbb0de6bff544676 100644 (file)
@@ -499,7 +499,6 @@ int mount_setup(bool loaded_policy, bool leave_propagation) {
          * use the same label for all their files. */
         if (loaded_policy) {
                 usec_t before_relabel, after_relabel;
-                char timespan[FORMAT_TIMESPAN_MAX];
                 const char *i;
                 int n_extra;
 
@@ -516,7 +515,7 @@ int mount_setup(bool loaded_policy, bool leave_propagation) {
 
                 log_info("Relabelled /dev, /dev/shm, /run, /sys/fs/cgroup%s in %s.",
                          n_extra > 0 ? ", additional files" : "",
-                         format_timespan(timespan, sizeof(timespan), after_relabel - before_relabel, 0));
+                         FORMAT_TIMESPAN(after_relabel - before_relabel, 0));
         }
 #endif
 
index 594efea989477c11e3c44c1855b7d18efcb399d2..cf8ca8d9d3f66a5cf9c6fd8a02bbaeae7a7bb51f 100644 (file)
@@ -11,6 +11,7 @@
 
 #include "alloc-util.h"
 #include "dissect-image.h"
+#include "exec-util.h"
 #include "extract-word.h"
 #include "fd-util.h"
 #include "fileio.h"
@@ -1010,11 +1011,9 @@ static int make_userns(uid_t uid_shift, uid_t uid_range) {
         r = safe_fork("(sd-mkuserns)", FORK_CLOSE_ALL_FDS|FORK_DEATHSIG|FORK_NEW_USERNS, &pid);
         if (r < 0)
                 return r;
-        if (r == 0) {
+        if (r == 0)
                 /* Child. We do nothing here, just freeze until somebody kills us. */
                 freeze();
-                _exit(EXIT_FAILURE);
-        }
 
         xsprintf(line, UID_FMT " " UID_FMT " " UID_FMT "\n", 0, uid_shift, uid_range);
 
index dfc47c423441a1aea646cac6c7c9fcd2f12141da..19e16d93455c88662e040e97d19f10ef014e335d 100644 (file)
@@ -1,5 +1,5 @@
 /* SPDX-License-Identifier: LGPL-2.1-or-later */
-#include <sys/poll.h>
+#include <poll.h>
 
 #include "fd-util.h"
 #include "io-util.h"
index 137ba77b3a6ea700396cce26608e02f230ee7734..7983c0a33afc7ed3d05d1d0d24716564280b85c8 100644 (file)
@@ -19,6 +19,7 @@
 #include "util.h"
 
 bool urlify_enabled(void) {
+#if ENABLE_URLIFY
         static int cached_urlify_enabled = -1;
 
         if (cached_urlify_enabled < 0) {
@@ -32,6 +33,9 @@ bool urlify_enabled(void) {
         }
 
         return cached_urlify_enabled;
+#else
+        return 0;
+#endif
 }
 
 int terminal_urlify(const char *url, const char *text, char **ret) {
index 900a7fb5fff2cb2bf0e1a856d762be3440d86846..dffb9cf6ee8bf9affc44b8a0b4496d68be2a03b4 100644 (file)
@@ -19,6 +19,9 @@
 #include "stat-util.h"
 #include "string-util.h"
 
+/* We treat tmpfs/ramfs + cgroupfs as non-physical file sytems. cgroupfs is similar to tmpfs in a way after
+ * all: we can create arbitrary directory hierarchies in it, and hence can also use rm_rf() on it to remove
+ * those again. */
 static bool is_physical_fs(const struct statfs *sfs) {
         return !is_temporary_fs(sfs) && !is_cgroup_fs(sfs);
 }
@@ -113,133 +116,145 @@ int fstatat_harder(int dfd,
         return 0;
 }
 
-int rm_rf_children(int fd, RemoveFlags flags, struct stat *root_dev) {
-        _cleanup_closedir_ DIR *d = NULL;
-        struct dirent *de;
-        int ret = 0, r;
-        struct statfs sfs;
+static int rm_rf_children_inner(
+                int fd,
+                const char *fname,
+                int is_dir,
+                RemoveFlags flags,
+                const struct stat *root_dev) {
 
-        assert(fd >= 0);
+        struct stat st;
+        int r;
 
-        /* This returns the first error we run into, but nevertheless tries to go on. This closes the passed
-         * fd, in all cases, including on failure.. */
+        assert(fd >= 0);
+        assert(fname);
 
-        if (!(flags & REMOVE_PHYSICAL)) {
+        if (is_dir < 0 || (is_dir > 0 && (root_dev || (flags & REMOVE_SUBVOLUME)))) {
 
-                r = fstatfs(fd, &sfs);
-                if (r < 0) {
-                        safe_close(fd);
-                        return -errno;
-                }
+                r = fstatat_harder(fd, fname, &st, AT_SYMLINK_NOFOLLOW, flags);
+                if (r < 0)
+                        return r;
 
-                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. */
-                        _cleanup_free_ char *path = NULL;
+                is_dir = S_ISDIR(st.st_mode);
+        }
 
-                        (void) fd_get_path(fd, &path);
-                        log_error("Attempted to remove disk file system under \"%s\", and we can't allow that.",
-                                  strna(path));
+        if (is_dir) {
+                _cleanup_close_ int subdir_fd = -1;
+                int q;
 
-                        safe_close(fd);
-                        return -EPERM;
-                }
-        }
+                /* if root_dev is set, remove subdirectories only if device is same */
+                if (root_dev && st.st_dev != root_dev->st_dev)
+                        return 0;
 
-        d = fdopendir(fd);
-        if (!d) {
-                safe_close(fd);
-                return errno == ENOENT ? 0 : -errno;
-        }
+                /* Stop at mount points */
+                r = fd_is_mount_point(fd, fname, 0);
+                if (r < 0)
+                        return r;
+                if (r > 0)
+                        return 0;
 
-        FOREACH_DIRENT_ALL(de, d, return -errno) {
-                bool is_dir;
-                struct stat st;
+                if ((flags & REMOVE_SUBVOLUME) && btrfs_might_be_subvol(&st)) {
 
-                if (dot_or_dot_dot(de->d_name))
-                        continue;
+                        /* This could be a subvolume, try to remove it */
 
-                if (de->d_type == DT_UNKNOWN ||
-                    (de->d_type == DT_DIR && (root_dev || (flags & REMOVE_SUBVOLUME)))) {
-                        r = fstatat_harder(fd, de->d_name, &st, AT_SYMLINK_NOFOLLOW, flags);
+                        r = btrfs_subvol_remove_fd(fd, fname, BTRFS_REMOVE_RECURSIVE|BTRFS_REMOVE_QUOTA);
                         if (r < 0) {
-                                if (ret == 0 && r != -ENOENT)
-                                        ret = r;
-                                continue;
-                        }
+                                if (!IN_SET(r, -ENOTTY, -EINVAL))
+                                        return r;
 
-                        is_dir = S_ISDIR(st.st_mode);
-                } else
-                        is_dir = de->d_type == DT_DIR;
+                                /* ENOTTY, then it wasn't a btrfs subvolume, continue below. */
+                        } else
+                                /* It was a subvolume, done. */
+                                return 1;
+                }
 
-                if (is_dir) {
-                        _cleanup_close_ int subdir_fd = -1;
+                subdir_fd = openat(fd, fname, O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|O_NOFOLLOW|O_NOATIME);
+                if (subdir_fd < 0)
+                        return -errno;
 
-                        /* if root_dev is set, remove subdirectories only if device is same */
-                        if (root_dev && st.st_dev != root_dev->st_dev)
-                                continue;
+                /* We pass REMOVE_PHYSICAL here, to avoid doing the fstatfs() to check the file system type
+                 * again for each directory */
+                q = rm_rf_children(TAKE_FD(subdir_fd), flags | REMOVE_PHYSICAL, root_dev);
 
-                        subdir_fd = openat(fd, de->d_name, O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|O_NOFOLLOW|O_NOATIME);
-                        if (subdir_fd < 0) {
-                                if (ret == 0 && errno != ENOENT)
-                                        ret = -errno;
-                                continue;
-                        }
+                r = unlinkat_harder(fd, fname, AT_REMOVEDIR, flags);
+                if (r < 0)
+                        return r;
+                if (q < 0)
+                        return q;
 
-                        /* Stop at mount points */
-                        r = fd_is_mount_point(fd, de->d_name, 0);
-                        if (r < 0) {
-                                if (ret == 0 && r != -ENOENT)
-                                        ret = r;
+                return 1;
 
-                                continue;
-                        }
-                        if (r > 0)
-                                continue;
+        } else if (!(flags & REMOVE_ONLY_DIRECTORIES)) {
+                r = unlinkat_harder(fd, fname, 0, flags);
+                if (r < 0)
+                        return r;
 
-                        if ((flags & REMOVE_SUBVOLUME) && btrfs_might_be_subvol(&st)) {
+                return 1;
+        }
 
-                                /* This could be a subvolume, try to remove it */
+        return 0;
+}
 
-                                r = btrfs_subvol_remove_fd(fd, de->d_name, BTRFS_REMOVE_RECURSIVE|BTRFS_REMOVE_QUOTA);
-                                if (r < 0) {
-                                        if (!IN_SET(r, -ENOTTY, -EINVAL)) {
-                                                if (ret == 0)
-                                                        ret = r;
+int rm_rf_children(
+                int fd,
+                RemoveFlags flags,
+                const struct stat *root_dev) {
 
-                                                continue;
-                                        }
+        _cleanup_closedir_ DIR *d = NULL;
+        struct dirent *de;
+        int ret = 0, r;
 
-                                        /* ENOTTY, then it wasn't a btrfs subvolume, continue below. */
-                                } else
-                                        /* It was a subvolume, continue. */
-                                        continue;
-                        }
+        assert(fd >= 0);
+
+        /* This returns the first error we run into, but nevertheless tries to go on. This closes the passed
+         * fd, in all cases, including on failure. */
+
+        d = fdopendir(fd);
+        if (!d) {
+                safe_close(fd);
+                return -errno;
+        }
 
-                        /* We pass REMOVE_PHYSICAL here, to avoid doing the fstatfs() to check the file
-                         * system type again for each directory */
-                        r = rm_rf_children(TAKE_FD(subdir_fd), flags | REMOVE_PHYSICAL, root_dev);
-                        if (r < 0 && ret == 0)
-                                ret = r;
+        if (!(flags & REMOVE_PHYSICAL)) {
+                struct statfs sfs;
 
-                        r = unlinkat_harder(fd, de->d_name, AT_REMOVEDIR, flags);
-                        if (r < 0 && r != -ENOENT && ret == 0)
-                                ret = r;
+                if (fstatfs(dirfd(d), &sfs) < 0)
+                        return -errno;
+
+                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. */
 
-                } else if (!(flags & REMOVE_ONLY_DIRECTORIES)) {
+                        _cleanup_free_ char *path = NULL;
 
-                        r = unlinkat_harder(fd, de->d_name, 0, flags);
-                        if (r < 0 && r != -ENOENT && ret == 0)
-                                ret = r;
+                        (void) fd_get_path(fd, &path);
+                        return log_error_errno(SYNTHETIC_ERRNO(EPERM),
+                                               "Attempted to remove disk file system under \"%s\", and we can't allow that.",
+                                               strna(path));
                 }
         }
+
+        FOREACH_DIRENT_ALL(de, d, return -errno) {
+                int is_dir;
+
+                if (dot_or_dot_dot(de->d_name))
+                        continue;
+
+                is_dir =
+                        de->d_type == DT_UNKNOWN ? -1 :
+                        de->d_type == DT_DIR;
+
+                r = rm_rf_children_inner(dirfd(d), de->d_name, is_dir, flags, root_dev);
+                if (r < 0 && r != -ENOENT && ret == 0)
+                        ret = r;
+        }
+
         return ret;
 }
 
 int rm_rf(const char *path, RemoveFlags flags) {
         int fd, r;
-        struct statfs s;
 
         assert(path);
 
@@ -284,9 +299,10 @@ int rm_rf(const char *path, RemoveFlags flags) {
                 if (FLAGS_SET(flags, REMOVE_ROOT)) {
 
                         if (!FLAGS_SET(flags, REMOVE_PHYSICAL)) {
+                                struct statfs s;
+
                                 if (statfs(path, &s) < 0)
                                         return -errno;
-
                                 if (is_physical_fs(&s))
                                         return log_error_errno(SYNTHETIC_ERRNO(EPERM),
                                                                "Attempted to remove files from a disk file system under \"%s\", refusing.",
@@ -314,3 +330,22 @@ int rm_rf(const char *path, RemoveFlags flags) {
 
         return r;
 }
+
+int rm_rf_child(int fd, const char *name, RemoveFlags flags) {
+
+        /* Removes one specific child of the specified directory */
+
+        if (fd < 0)
+                return -EBADF;
+
+        if (!filename_is_valid(name))
+                return -EINVAL;
+
+        if ((flags & (REMOVE_ROOT|REMOVE_MISSING_OK)) != 0) /* Doesn't really make sense here, we are not supposed to remove 'fd' anyway */
+                return -EINVAL;
+
+        if (FLAGS_SET(flags, REMOVE_ONLY_DIRECTORIES|REMOVE_SUBVOLUME))
+                return -EINVAL;
+
+        return rm_rf_children_inner(fd, name, -1, flags, NULL);
+}
index 40f0894c96dfa639dd4299ba52108c025ae03ed8..577a2795e0f34f7834128a21f64e7ca5af82aa99 100644 (file)
@@ -23,7 +23,8 @@ int fstatat_harder(int dfd,
                 int fstatat_flags,
                 RemoveFlags remove_flags);
 
-int rm_rf_children(int fd, RemoveFlags flags, struct stat *root_dev);
+int rm_rf_children(int fd, RemoveFlags flags, const struct stat *root_dev);
+int rm_rf_child(int fd, const char *name, RemoveFlags flags);
 int rm_rf(const char *path, RemoveFlags flags);
 
 /* Useful for usage with _cleanup_(), destroys a directory and frees the pointer */
index e0f88aec73a556b804835ee1e91787f524b723eb..631ca5dd34eb4c1168a89ade5942410bda21227e 100644 (file)
@@ -310,6 +310,7 @@ const SyscallFilterSet syscall_filter_sets[_SYSCALL_FILTER_SET_MAX] = {
                 "getpgrp\0"
                 "getpid\0"
                 "getppid\0"
+                "getrandom\0"
                 "getresgid\0"
                 "getresgid32\0"
                 "getresuid\0"
@@ -330,6 +331,7 @@ const SyscallFilterSet syscall_filter_sets[_SYSCALL_FILTER_SET_MAX] = {
                 "restart_syscall\0"
                 "rseq\0"
                 "rt_sigreturn\0"
+                "sched_getaffinity\0"
                 "sched_yield\0"
                 "set_robust_list\0"
                 "set_thread_area\0"
@@ -858,7 +860,6 @@ const SyscallFilterSet syscall_filter_sets[_SYSCALL_FILTER_SET_MAX] = {
                 "get_mempolicy\0"
                 "getcpu\0"
                 "getpriority\0"
-                "getrandom\0"
                 "ioctl\0"
                 "ioprio_get\0"
                 "kcmp\0"
@@ -874,7 +875,6 @@ const SyscallFilterSet syscall_filter_sets[_SYSCALL_FILTER_SET_MAX] = {
                 "remap_file_pages\0"
                 "sched_get_priority_max\0"
                 "sched_get_priority_min\0"
-                "sched_getaffinity\0"
                 "sched_getattr\0"
                 "sched_getparam\0"
                 "sched_getscheduler\0"
index 03cee76f64a770f49184c063272e597b568a883b..e4890e8170dd1997d147c6aba5a2d5789caa96ad 100644 (file)
@@ -115,7 +115,6 @@ REENABLE_WARNING
 static int open_label_db(void) {
         struct selabel_handle *hnd;
         usec_t before_timestamp, after_timestamp;
-        char timespan[FORMAT_TIMESPAN_MAX];
 
 #  if HAVE_GENERIC_MALLINFO
         generic_mallinfo before_mallinfo = generic_mallinfo_get();
@@ -131,11 +130,11 @@ static int open_label_db(void) {
         generic_mallinfo after_mallinfo = generic_mallinfo_get();
         size_t l = LESS_BY((size_t) after_mallinfo.uordblks, (size_t) before_mallinfo.uordblks);
         log_debug("Successfully loaded SELinux database in %s, size on heap is %zuK.",
-                  format_timespan(timespan, sizeof(timespan), after_timestamp - before_timestamp, 0),
+                  FORMAT_TIMESPAN(after_timestamp - before_timestamp, 0),
                   DIV_ROUND_UP(l, 1024));
 #  else
         log_debug("Successfully loaded SELinux database in %s.",
-                  format_timespan(timespan, sizeof(timespan), after_timestamp - before_timestamp, 0));
+                  FORMAT_TIMESPAN(after_timestamp - before_timestamp, 0));
 #  endif
 
         /* release memory after measurement */
index 23aac3ef527112b2010a31ee2b14a84631625445..47996b9ead64bb6cbc3c06a3cdb417f28eb27fd7 100644 (file)
@@ -176,6 +176,7 @@ int deserialize_dual_timestamp(const char *value, dual_timestamp *t) {
 
 int deserialize_environment(const char *value, char ***list) {
         _cleanup_free_ char *unescaped = NULL;
+        ssize_t l;
         int r;
 
         assert(value);
@@ -183,9 +184,9 @@ int deserialize_environment(const char *value, char ***list) {
 
         /* Changes the *environment strv inline. */
 
-        r = cunescape(value, 0, &unescaped);
-        if (r < 0)
-                return log_error_errno(r, "Failed to unescape: %m");
+        l = cunescape(value, 0, &unescaped);
+        if (l < 0)
+                return log_error_errno(l, "Failed to unescape: %m");
 
         r = strv_env_replace_consume(list, TAKE_PTR(unescaped));
         if (r < 0)
index 092be6ee7f620ba062b41ae99a66a280b4992c2c..99b1108b7721221f5b6297ff06711618b79ceaed 100644 (file)
@@ -76,7 +76,7 @@ int service_parse_argv(
                         return -EINVAL;
 
                 default:
-                        assert_not_reached("Unknown option code.");
+                        assert_not_reached();
                 }
 
         if (optind < argc)
index 0c044378265f06c45dcfd5a584d0a2984766f731..494047a5d159d21f8218fd1c7dc54d920bc4cb91 100644 (file)
@@ -129,7 +129,7 @@ int socket_address_parse(SocketAddress *a, const char *s) {
                                         .size = sizeof(struct sockaddr_in6),
                                 };
                         else
-                                assert_not_reached("Family quarrel");
+                                assert_not_reached();
                 }
         }
 
index 1f07b198fa151ba898e525efc6ab90853b43741d..38fab212034c787cc2dd98a86849cf79a70380d1 100644 (file)
@@ -4,6 +4,7 @@
 #include <stdlib.h>
 #include <unistd.h>
 
+#include "exec-util.h"
 #include "log.h"
 #include "process-util.h"
 #include "spawn-ask-password-agent.h"
index a0024eb2ea00084eeb1f9d09e117be32c9f001c5..cd0b4601da1159f979713689b1d10401e9318977 100644 (file)
@@ -6,6 +6,7 @@
 #include <stdlib.h>
 #include <unistd.h>
 
+#include "exec-util.h"
 #include "fd-util.h"
 #include "io-util.h"
 #include "log.h"
index ab7d799029654a66f43984c45aa78954845d2a45..175b6d5499c83ed4a6b454ac9e79808436dcb268 100644 (file)
@@ -160,7 +160,7 @@ bool have_namespaces(void) {
         if (si.si_status == EXIT_FAILURE)
                 return false;
 
-        assert_not_reached("unexpected exit code");
+        assert_not_reached();
 }
 
 bool can_memlock(void) {
index df6d2eef58841342eea9bfcd69c1ebf8ac948902..5cb6563b4346aab58ef9014693e84fcd7a78293c 100644 (file)
@@ -25,6 +25,7 @@ TSS2_RC (*sym_Esys_CreatePrimary)(ESYS_CONTEXT *esysContext, ESYS_TR primaryHand
 void (*sym_Esys_Finalize)(ESYS_CONTEXT **context) = NULL;
 TSS2_RC (*sym_Esys_FlushContext)(ESYS_CONTEXT *esysContext, ESYS_TR flushHandle) = NULL;
 void (*sym_Esys_Free)(void *ptr) = NULL;
+TSS2_RC (*sym_Esys_GetCapability)(ESYS_CONTEXT *esysContext, ESYS_TR shandle1, ESYS_TR shandle2, ESYS_TR shandle3, TPM2_CAP capability, UINT32 property, UINT32 propertyCount, TPMI_YES_NO *moreData, TPMS_CAPABILITY_DATA **capabilityData);
 TSS2_RC (*sym_Esys_GetRandom)(ESYS_CONTEXT *esysContext, ESYS_TR shandle1, ESYS_TR shandle2, ESYS_TR shandle3, UINT16 bytesRequested, TPM2B_DIGEST **randomBytes) = NULL;
 TSS2_RC (*sym_Esys_Initialize)(ESYS_CONTEXT **esys_context,  TSS2_TCTI_CONTEXT *tcti, TSS2_ABI_VERSION *abiVersion) = NULL;
 TSS2_RC (*sym_Esys_Load)(ESYS_CONTEXT *esysContext, ESYS_TR parentHandle, ESYS_TR shandle1, ESYS_TR shandle2, ESYS_TR shandle3, const TPM2B_PRIVATE *inPrivate, const TPM2B_PUBLIC *inPublic, ESYS_TR *objectHandle) = NULL;
@@ -51,6 +52,7 @@ int dlopen_tpm2(void) {
                         DLSYM_ARG(Esys_Finalize),
                         DLSYM_ARG(Esys_FlushContext),
                         DLSYM_ARG(Esys_Free),
+                        DLSYM_ARG(Esys_GetCapability),
                         DLSYM_ARG(Esys_GetRandom),
                         DLSYM_ARG(Esys_Initialize),
                         DLSYM_ARG(Esys_Load),
@@ -310,11 +312,93 @@ static int tpm2_make_primary(
         return 0;
 }
 
+static int tpm2_get_best_pcr_bank(
+                ESYS_CONTEXT *c,
+                TPMI_ALG_HASH *ret) {
+
+        _cleanup_(Esys_Freep) TPMS_CAPABILITY_DATA *pcap = NULL;
+        TPMI_ALG_HASH hash = TPM2_ALG_SHA1;
+        bool found = false;
+        TPMI_YES_NO more;
+        TSS2_RC rc;
+
+        rc = sym_Esys_GetCapability(
+                        c,
+                        ESYS_TR_NONE,
+                        ESYS_TR_NONE,
+                        ESYS_TR_NONE,
+                        TPM2_CAP_PCRS,
+                        0,
+                        1,
+                        &more,
+                        &pcap);
+        if (rc != TSS2_RC_SUCCESS)
+                return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
+                                       "Failed to determine TPM2 PCR bank capabilities: %s", sym_Tss2_RC_Decode(rc));
+
+        assert(pcap->capability == TPM2_CAP_PCRS);
+
+        for (size_t i = 0; i < pcap->data.assignedPCR.count; i++) {
+                bool valid = true;
+
+                /* As per
+                 * https://trustedcomputinggroup.org/wp-content/uploads/TCG_PCClient_PFP_r1p05_v23_pub.pdf a
+                 * TPM2 on a Client PC must have at least 24 PCRs. If this TPM has less, just skip over
+                 * it. */
+                if (pcap->data.assignedPCR.pcrSelections[i].sizeofSelect < TPM2_PCRS_MAX/8) {
+                        log_debug("Skipping TPM2 PCR bank %s with fewer than 24 PCRs.",
+                                  strna(tpm2_pcr_bank_to_string(pcap->data.assignedPCR.pcrSelections[i].hash)));
+                        continue;
+                }
+
+                assert_cc(TPM2_PCRS_MAX % 8 == 0);
+
+                /* It's not enought to check how many PCRs there are, we also need to check that the 24 are
+                 * enabled for this bank. Otherwise this TPM doesn't qualify. */
+                for (size_t j = 0; j < TPM2_PCRS_MAX/8; j++)
+                        if (pcap->data.assignedPCR.pcrSelections[i].pcrSelect[j] != 0xFF) {
+                                valid = false;
+                                break;
+                        }
+
+                if (!valid) {
+                        log_debug("TPM2 PCR bank %s has fewer than 24 PCR bits enabled, ignoring.",
+                                  strna(tpm2_pcr_bank_to_string(pcap->data.assignedPCR.pcrSelections[i].hash)));
+                        continue;
+                }
+
+                if (pcap->data.assignedPCR.pcrSelections[i].hash == TPM2_ALG_SHA256) {
+                        hash = TPM2_ALG_SHA256;
+                        found = true;
+                        break;
+                }
+
+                if (pcap->data.assignedPCR.pcrSelections[i].hash == TPM2_ALG_SHA1)
+                        found = true;
+        }
+
+        if (!found)
+                return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP),
+                                       "TPM2 module supports neither SHA1 nor SHA256 PCR banks, cannot operate.");
+
+        if (hash == TPM2_ALG_SHA256)
+                log_debug("TPM2 device supports SHA256 PCR banks, yay!");
+        else {
+                assert(hash == TPM2_ALG_SHA1);
+                log_debug("TPM2 device lacks support for SHA256 PCR banks, falling back to SHA1 banks.");
+        }
+
+        *ret = hash;
+        return 0;
+}
+
 static int tpm2_make_pcr_session(
                 ESYS_CONTEXT *c,
                 uint32_t pcr_mask,
+                uint16_t pcr_bank, /* If UINT16_MAX, pick best bank automatically, otherwise specify bank explicitly. */
                 ESYS_TR *ret_session,
-                TPM2B_DIGEST **ret_policy_digest) {
+                TPM2B_DIGEST **ret_policy_digest,
+                TPMI_ALG_HASH *ret_pcr_bank) {
 
         static const TPMT_SYM_DEF symmetric = {
                 .algorithm = TPM2_ALG_AES,
@@ -327,7 +411,7 @@ static int tpm2_make_pcr_session(
         };
         TPML_PCR_SELECTION pcr_selection = {
                 .count = 1,
-                .pcrSelections[0].hash = TPM2_ALG_SHA256,
+                .pcrSelections[0].hash = TPM2_ALG_SHA256, /* overriden below, depending on TPM2 capabilities */
                 .pcrSelections[0].sizeofSelect = 3,
                 .pcrSelections[0].pcrSelect[0] = pcr_mask & 0xFF,
                 .pcrSelections[0].pcrSelect[1] = (pcr_mask >> 8) & 0xFF,
@@ -342,6 +426,16 @@ static int tpm2_make_pcr_session(
 
         log_debug("Starting authentication session.");
 
+        if (pcr_bank != UINT16_MAX)
+                pcr_selection.pcrSelections[0].hash = pcr_bank;
+        else {
+                /* No bank configured, pick automatically. Some TPM2 devices only can do SHA1. If we detect
+                 * that use that, but preferably use SHA256 */
+                r = tpm2_get_best_pcr_bank(c, &pcr_selection.pcrSelections[0].hash);
+                if (r < 0)
+                        return r;
+        }
+
         rc = sym_Esys_StartAuthSession(
                         c,
                         ESYS_TR_NONE,
@@ -412,6 +506,9 @@ static int tpm2_make_pcr_session(
         if (ret_policy_digest)
                 *ret_policy_digest = TAKE_PTR(policy_digest);
 
+        if (ret_pcr_bank)
+                *ret_pcr_bank = pcr_selection.pcrSelections[0].hash;
+
         r = 0;
 
 finish:
@@ -427,7 +524,8 @@ int tpm2_seal(
                 void **ret_blob,
                 size_t *ret_blob_size,
                 void **ret_pcr_hash,
-                size_t *ret_pcr_hash_size) {
+                size_t *ret_pcr_hash_size,
+                uint16_t *ret_pcr_bank) {
 
         _cleanup_(tpm2_context_destroy) struct tpm2_context c = {};
         _cleanup_(Esys_Freep) TPM2B_DIGEST *policy_digest = NULL;
@@ -439,6 +537,7 @@ int tpm2_seal(
         TPM2B_SENSITIVE_CREATE hmac_sensitive;
         ESYS_TR primary = ESYS_TR_NONE;
         TPM2B_PUBLIC hmac_template;
+        TPMI_ALG_HASH pcr_bank;
         size_t k, blob_size;
         usec_t start;
         TSS2_RC rc;
@@ -450,6 +549,7 @@ int tpm2_seal(
         assert(ret_blob_size);
         assert(ret_pcr_hash);
         assert(ret_pcr_hash_size);
+        assert(ret_pcr_bank);
 
         assert(pcr_mask < (UINT32_C(1) << TPM2_PCRS_MAX)); /* Support 24 PCR banks */
 
@@ -478,7 +578,7 @@ int tpm2_seal(
         if (r < 0)
                 return r;
 
-        r = tpm2_make_pcr_session(c.esys_context, pcr_mask, NULL, &policy_digest);
+        r = tpm2_make_pcr_session(c.esys_context, pcr_mask, UINT16_MAX, NULL, &policy_digest, &pcr_bank);
         if (r < 0)
                 goto finish;
 
@@ -591,10 +691,8 @@ int tpm2_seal(
         if (!hash)
                 return log_oom();
 
-        if (DEBUG_LOGGING) {
-                char buf[FORMAT_TIMESPAN_MAX];
-                log_debug("Completed TPM2 key sealing in %s.", format_timespan(buf, sizeof(buf), now(CLOCK_MONOTONIC) - start, 1));
-        }
+        if (DEBUG_LOGGING)
+                log_debug("Completed TPM2 key sealing in %s.", FORMAT_TIMESPAN(now(CLOCK_MONOTONIC) - start, 1));
 
         *ret_secret = TAKE_PTR(secret);
         *ret_secret_size = hmac_sensitive.sensitive.data.size;
@@ -602,6 +700,7 @@ int tpm2_seal(
         *ret_blob_size = blob_size;
         *ret_pcr_hash = TAKE_PTR(hash);
         *ret_pcr_hash_size = policy_digest->size;
+        *ret_pcr_bank = pcr_bank;
 
         r = 0;
 
@@ -613,6 +712,7 @@ finish:
 int tpm2_unseal(
                 const char *device,
                 uint32_t pcr_mask,
+                uint16_t pcr_bank,
                 const void *blob,
                 size_t blob_size,
                 const void *known_policy_hash,
@@ -672,7 +772,7 @@ int tpm2_unseal(
         if (r < 0)
                 return r;
 
-        r = tpm2_make_pcr_session(c.esys_context, pcr_mask, &session, &policy_digest);
+        r = tpm2_make_pcr_session(c.esys_context, pcr_mask, pcr_bank, &session, &policy_digest, NULL);
         if (r < 0)
                 goto finish;
 
@@ -726,10 +826,8 @@ int tpm2_unseal(
                 goto finish;
         }
 
-        if (DEBUG_LOGGING) {
-                char buf[FORMAT_TIMESPAN_MAX];
-                log_debug("Completed TPM2 key unsealing in %s.", format_timespan(buf, sizeof(buf), now(CLOCK_MONOTONIC) - start, 1));
-        }
+        if (DEBUG_LOGGING)
+                log_debug("Completed TPM2 key unsealing in %s.", FORMAT_TIMESPAN(now(CLOCK_MONOTONIC) - start, 1));
 
         *ret_secret = TAKE_PTR(secret);
         *ret_secret_size = unsealed->size;
@@ -913,6 +1011,7 @@ int tpm2_parse_pcrs(const char *s, uint32_t *ret) {
 int tpm2_make_luks2_json(
                 int keyslot,
                 uint32_t pcr_mask,
+                uint16_t pcr_bank,
                 const void *blob,
                 size_t blob_size,
                 const void *policy_hash,
@@ -955,6 +1054,7 @@ int tpm2_make_luks2_json(
                                        JSON_BUILD_PAIR("keyslots", JSON_BUILD_ARRAY(JSON_BUILD_STRING(keyslot_as_string))),
                                        JSON_BUILD_PAIR("tpm2-blob", JSON_BUILD_BASE64(blob, blob_size)),
                                        JSON_BUILD_PAIR("tpm2-pcrs", JSON_BUILD_VARIANT(a)),
+                                       JSON_BUILD_PAIR_CONDITION(!!tpm2_pcr_bank_to_string(pcr_bank), "tpm2-pcr-bank", JSON_BUILD_STRING(tpm2_pcr_bank_to_string(pcr_bank))),
                                        JSON_BUILD_PAIR("tpm2-policy-hash", JSON_BUILD_HEX(policy_hash, policy_hash_size))));
         if (r < 0)
                 return r;
@@ -964,3 +1064,36 @@ int tpm2_make_luks2_json(
 
         return keyslot;
 }
+
+/* We want the helpers below to work also if TPM2 libs are not available, hence define these two defines if
+ * they are missing. */
+#ifndef TPM2_ALG_SHA256
+#define TPM2_ALG_SHA256 0xB
+#endif
+
+#ifndef TPM2_ALG_SHA1
+#define TPM2_ALG_SHA1 0x4
+#endif
+
+int tpm2_pcr_bank_supported(uint16_t bank) {
+        /* For now, let's officially only support these two. We can extend this later on, should the need
+         * arise. */
+        return IN_SET(bank, TPM2_ALG_SHA256, TPM2_ALG_SHA1);
+}
+
+const char *tpm2_pcr_bank_to_string(uint16_t bank) {
+        /* Similar here, only support the two for now, we can always extend this later.  */
+        if (bank == TPM2_ALG_SHA256)
+                return "sha256";
+        if (bank == TPM2_ALG_SHA1)
+                return "sha1";
+        return NULL;
+}
+
+int tpm2_pcr_bank_from_string(const char *bank) {
+        if (streq_ptr(bank, "sha256"))
+                return TPM2_ALG_SHA256;
+        if (streq_ptr(bank, "sha1"))
+                return TPM2_ALG_SHA1;
+        return -EINVAL;
+}
index 82cd186e1162c7056ad955cd3811ecdbb9d19cdf..8032afe7b000ea4d64e480f47d1a59bd12ecc68e 100644 (file)
@@ -15,6 +15,7 @@ extern TSS2_RC (*sym_Esys_CreatePrimary)(ESYS_CONTEXT *esysContext, ESYS_TR prim
 extern void (*sym_Esys_Finalize)(ESYS_CONTEXT **context);
 extern TSS2_RC (*sym_Esys_FlushContext)(ESYS_CONTEXT *esysContext, ESYS_TR flushHandle);
 extern void (*sym_Esys_Free)(void *ptr);
+extern TSS2_RC (*sym_Esys_GetCapability)(ESYS_CONTEXT *esysContext, ESYS_TR shandle1, ESYS_TR shandle2, ESYS_TR shandle3, TPM2_CAP capability, UINT32 property, UINT32 propertyCount, TPMI_YES_NO *moreData, TPMS_CAPABILITY_DATA **capabilityData);
 extern TSS2_RC (*sym_Esys_GetRandom)(ESYS_CONTEXT *esysContext, ESYS_TR shandle1, ESYS_TR shandle2, ESYS_TR shandle3, UINT16 bytesRequested, TPM2B_DIGEST **randomBytes);
 extern TSS2_RC (*sym_Esys_Initialize)(ESYS_CONTEXT **esys_context,  TSS2_TCTI_CONTEXT *tcti, TSS2_ABI_VERSION *abiVersion);
 extern TSS2_RC (*sym_Esys_Load)(ESYS_CONTEXT *esysContext, ESYS_TR parentHandle, ESYS_TR shandle1, ESYS_TR shandle2, ESYS_TR shandle3, const TPM2B_PRIVATE *inPrivate, const TPM2B_PUBLIC *inPublic, ESYS_TR *objectHandle);
@@ -33,8 +34,8 @@ extern TSS2_RC (*sym_Tss2_MU_TPM2B_PUBLIC_Unmarshal)(uint8_t const buffer[], siz
 
 int dlopen_tpm2(void);
 
-int tpm2_seal(const char *device, uint32_t pcr_mask, void **ret_secret, size_t *ret_secret_size, void **ret_blob, size_t *ret_blob_size, void **ret_pcr_hash, size_t *ret_pcr_hash_size);
-int tpm2_unseal(const char *device, uint32_t pcr_mask, const void *blob, size_t blob_size, const void *pcr_hash, size_t pcr_hash_size, void **ret_secret, size_t *ret_secret_size);
+int tpm2_seal(const char *device, uint32_t pcr_mask, void **ret_secret, size_t *ret_secret_size, void **ret_blob, size_t *ret_blob_size, void **ret_pcr_hash, size_t *ret_pcr_hash_size, uint16_t *ret_pcr_bank);
+int tpm2_unseal(const char *device, uint32_t pcr_mask, uint16_t pcr_bank, const void *blob, size_t blob_size, const void *pcr_hash, size_t pcr_hash_size, void **ret_secret, size_t *ret_secret_size);
 
 #endif
 
@@ -43,9 +44,18 @@ int tpm2_find_device_auto(int log_level, char **ret);
 
 int tpm2_parse_pcrs(const char *s, uint32_t *ret);
 
-int tpm2_make_luks2_json(int keyslot, uint32_t pcr_mask, const void *blob, size_t blob_size, const void *policy_hash, size_t policy_hash_size, JsonVariant **ret);
+int tpm2_make_luks2_json(int keyslot, uint32_t pcr_mask, uint16_t pcr_bank, const void *blob, size_t blob_size, const void *policy_hash, size_t policy_hash_size, JsonVariant **ret);
 
 #define TPM2_PCRS_MAX 24
 
 /* Default to PCR 7 only */
 #define TPM2_PCR_MASK_DEFAULT (UINT32_C(1) << 7)
+
+int tpm2_pcr_bank_supported(uint16_t bank);
+const char *tpm2_pcr_bank_to_string(uint16_t bank);
+int tpm2_pcr_bank_from_string(const char *bank);
+
+typedef struct {
+        uint32_t search_pcr_mask;
+        const char *device;
+} systemd_tpm2_plugin_params;
index f934fc157eb527d493293ba5e5e6e1cab6855992..27dfd11a6a7cc1518406b934274e11352ff12874 100644 (file)
@@ -351,7 +351,6 @@ void log_device_uevent(sd_device *device, const char *str) {
 
 int udev_rule_parse_value(char *str, char **ret_value, char **ret_endpos) {
         char *i, *j;
-        int r;
         bool is_escaped;
 
         /* value must be double quotated */
@@ -373,6 +372,7 @@ int udev_rule_parse_value(char *str, char **ret_value, char **ret_endpos) {
                 j[0] = '\0';
         } else {
                 _cleanup_free_ char *unescaped = NULL;
+                ssize_t l;
 
                 /* find the end position of value */
                 for (i = str; *i != '"'; i++) {
@@ -383,11 +383,12 @@ int udev_rule_parse_value(char *str, char **ret_value, char **ret_endpos) {
                 }
                 i[0] = '\0';
 
-                r = cunescape_length(str, i - str, 0, &unescaped);
-                if (r < 0)
-                        return r;
-                assert(r <= i - str);
-                memcpy(str, unescaped, r + 1);
+                l = cunescape_length(str, i - str, 0, &unescaped);
+                if (l < 0)
+                        return l;
+
+                assert(l <= i - str);
+                memcpy(str, unescaped, l + 1);
         }
 
         *ret_value = str;
index 29790282b4e2c648b231b083e8b287459e7a6a34..29aa5c0c7c4abbc68ec04fe673b31915c461ba2a 100644 (file)
@@ -43,8 +43,7 @@ void user_record_show(UserRecord *hr, bool show_full_group_info) {
         printf(" Disposition: %s\n", user_disposition_to_string(user_record_disposition(hr)));
 
         if (hr->last_change_usec != USEC_INFINITY) {
-                char buf[FORMAT_TIMESTAMP_MAX];
-                printf(" Last Change: %s\n", format_timestamp(buf, sizeof(buf), hr->last_change_usec));
+                printf(" Last Change: %s\n", FORMAT_TIMESTAMP(hr->last_change_usec));
 
                 if (hr->last_change_usec > now(CLOCK_REALTIME))
                         printf("              %sModification time lies in the future, system clock wrong?%s\n",
@@ -52,10 +51,8 @@ void user_record_show(UserRecord *hr, bool show_full_group_info) {
         }
 
         if (hr->last_password_change_usec != USEC_INFINITY &&
-            hr->last_password_change_usec != hr->last_change_usec) {
-                char buf[FORMAT_TIMESTAMP_MAX];
-                printf(" Last Passw.: %s\n", format_timestamp(buf, sizeof(buf), hr->last_password_change_usec));
-        }
+            hr->last_password_change_usec != hr->last_change_usec)
+                printf(" Last Passw.: %s\n", FORMAT_TIMESTAMP(hr->last_password_change_usec));
 
         r = user_record_test_blocked(hr);
         switch (r) {
@@ -238,15 +235,11 @@ void user_record_show(UserRecord *hr, bool show_full_group_info) {
         if (hr->locked >= 0)
                 printf("      Locked: %s\n", yes_no(hr->locked));
 
-        if (hr->not_before_usec != UINT64_MAX) {
-                char buf[FORMAT_TIMESTAMP_MAX];
-                printf("  Not Before: %s\n", format_timestamp(buf, sizeof(buf), hr->not_before_usec));
-        }
+        if (hr->not_before_usec != UINT64_MAX)
+                printf("  Not Before: %s\n", FORMAT_TIMESTAMP(hr->not_before_usec));
 
-        if (hr->not_after_usec != UINT64_MAX) {
-                char buf[FORMAT_TIMESTAMP_MAX];
-                printf("   Not After: %s\n", format_timestamp(buf, sizeof(buf), hr->not_after_usec));
-        }
+        if (hr->not_after_usec != UINT64_MAX)
+                printf("   Not After: %s\n", FORMAT_TIMESTAMP(hr->not_after_usec));
 
         if (hr->umask != MODE_INVALID)
                 printf("       UMask: 0%03o\n", hr->umask);
@@ -263,15 +256,11 @@ void user_record_show(UserRecord *hr, bool show_full_group_info) {
         if (hr->tasks_max != UINT64_MAX)
                 printf("   Tasks Max: %" PRIu64 "\n", hr->tasks_max);
 
-        if (hr->memory_high != UINT64_MAX) {
-                char buf[FORMAT_BYTES_MAX];
-                printf(" Memory High: %s\n", format_bytes(buf, sizeof(buf), hr->memory_high));
-        }
+        if (hr->memory_high != UINT64_MAX)
+                printf(" Memory High: %s\n", FORMAT_BYTES(hr->memory_high));
 
-        if (hr->memory_max != UINT64_MAX) {
-                char buf[FORMAT_BYTES_MAX];
-                printf("  Memory Max: %s\n", format_bytes(buf, sizeof(buf), hr->memory_max));
-        }
+        if (hr->memory_max != UINT64_MAX)
+                printf("  Memory Max: %s\n", FORMAT_BYTES(hr->memory_max));
 
         if (hr->cpu_weight != UINT64_MAX)
                 printf("  CPU Weight: %" PRIu64 "\n", hr->cpu_weight);
@@ -306,14 +295,11 @@ void user_record_show(UserRecord *hr, bool show_full_group_info) {
                         printf("  PBKDF Type: %s\n", hr->luks_pbkdf_type);
                 if (hr->luks_pbkdf_hash_algorithm)
                         printf("  PBKDF Hash: %s\n", hr->luks_pbkdf_hash_algorithm);
-                if (hr->luks_pbkdf_time_cost_usec != UINT64_MAX) {
-                        char buf[FORMAT_TIMESPAN_MAX];
-                        printf("  PBKDF Time: %s\n", format_timespan(buf, sizeof(buf), hr->luks_pbkdf_time_cost_usec, 0));
-                }
-                if (hr->luks_pbkdf_memory_cost != UINT64_MAX) {
-                        char buf[FORMAT_BYTES_MAX];
-                        printf(" PBKDF Bytes: %s\n", format_bytes(buf, sizeof(buf), hr->luks_pbkdf_memory_cost));
-                }
+                if (hr->luks_pbkdf_time_cost_usec != UINT64_MAX)
+                        printf("  PBKDF Time: %s\n", FORMAT_TIMESPAN(hr->luks_pbkdf_time_cost_usec, 0));
+                if (hr->luks_pbkdf_memory_cost != UINT64_MAX)
+                        printf(" PBKDF Bytes: %s\n", FORMAT_BYTES(hr->luks_pbkdf_memory_cost));
+
                 if (hr->luks_pbkdf_parallel_threads != UINT64_MAX)
                         printf("PBKDF Thread: %" PRIu64 "\n", hr->luks_pbkdf_parallel_threads);
 
@@ -337,28 +323,22 @@ void user_record_show(UserRecord *hr, bool show_full_group_info) {
         if (hr->skeleton_directory)
                 printf("  Skel. Dir.: %s\n", user_record_skeleton_directory(hr));
 
-        if (hr->disk_size != UINT64_MAX) {
-                char buf[FORMAT_BYTES_MAX];
-                printf("   Disk Size: %s\n", format_bytes(buf, sizeof(buf), hr->disk_size));
-        }
+        if (hr->disk_size != UINT64_MAX)
+                printf("   Disk Size: %s\n", FORMAT_BYTES(hr->disk_size));
 
         if (hr->disk_usage != UINT64_MAX) {
-                char buf[FORMAT_BYTES_MAX];
-
                 if (hr->disk_size != UINT64_MAX) {
                         unsigned permille;
 
                         permille = (unsigned) DIV_ROUND_UP(hr->disk_usage * 1000U, hr->disk_size); /* Round up! */
                         printf("  Disk Usage: %s (= %u.%01u%%)\n",
-                               format_bytes(buf, sizeof(buf), hr->disk_usage),
+                               FORMAT_BYTES(hr->disk_usage),
                                permille / 10, permille % 10);
                 } else
-                        printf("  Disk Usage: %s\n", format_bytes(buf, sizeof(buf), hr->disk_usage));
+                        printf("  Disk Usage: %s\n", FORMAT_BYTES(hr->disk_usage));
         }
 
         if (hr->disk_free != UINT64_MAX) {
-                char buf[FORMAT_BYTES_MAX];
-
                 if (hr->disk_size != UINT64_MAX) {
                         const char *color_on, *color_off;
                         unsigned permille;
@@ -381,38 +361,30 @@ void user_record_show(UserRecord *hr, bool show_full_group_info) {
 
                         printf("   Disk Free: %s%s (= %u.%01u%%)%s\n",
                                color_on,
-                               format_bytes(buf, sizeof(buf), hr->disk_free),
+                               FORMAT_BYTES(hr->disk_free),
                                permille / 10, permille % 10,
                                color_off);
                 } else
-                        printf("   Disk Free: %s\n", format_bytes(buf, sizeof(buf), hr->disk_free));
+                        printf("   Disk Free: %s\n", FORMAT_BYTES(hr->disk_free));
         }
 
-        if (hr->disk_floor != UINT64_MAX) {
-                char buf[FORMAT_BYTES_MAX];
-                printf("  Disk Floor: %s\n", format_bytes(buf, sizeof(buf), hr->disk_floor));
-        }
+        if (hr->disk_floor != UINT64_MAX)
+                printf("  Disk Floor: %s\n", FORMAT_BYTES(hr->disk_floor));
 
-        if (hr->disk_ceiling != UINT64_MAX) {
-                char buf[FORMAT_BYTES_MAX];
-                printf("Disk Ceiling: %s\n", format_bytes(buf, sizeof(buf), hr->disk_ceiling));
-        }
+        if (hr->disk_ceiling != UINT64_MAX)
+                printf("Disk Ceiling: %s\n", FORMAT_BYTES(hr->disk_ceiling));
 
         if (hr->good_authentication_counter != UINT64_MAX)
                 printf("  Good Auth.: %" PRIu64 "\n", hr->good_authentication_counter);
 
-        if (hr->last_good_authentication_usec != UINT64_MAX) {
-                char buf[FORMAT_TIMESTAMP_MAX];
-                printf("   Last Good: %s\n", format_timestamp(buf, sizeof(buf), hr->last_good_authentication_usec));
-        }
+        if (hr->last_good_authentication_usec != UINT64_MAX)
+                printf("   Last Good: %s\n", FORMAT_TIMESTAMP(hr->last_good_authentication_usec));
 
         if (hr->bad_authentication_counter != UINT64_MAX)
                 printf("   Bad Auth.: %" PRIu64 "\n", hr->bad_authentication_counter);
 
-        if (hr->last_bad_authentication_usec != UINT64_MAX) {
-                char buf[FORMAT_TIMESTAMP_MAX];
-                printf("    Last Bad: %s\n", format_timestamp(buf, sizeof(buf), hr->last_bad_authentication_usec));
-        }
+        if (hr->last_bad_authentication_usec != UINT64_MAX)
+                printf("    Last Bad: %s\n", FORMAT_TIMESTAMP(hr->last_bad_authentication_usec));
 
         t = user_record_ratelimit_next_try(hr);
         if (t != USEC_INFINITY) {
@@ -420,20 +392,16 @@ void user_record_show(UserRecord *hr, bool show_full_group_info) {
 
                 if (t <= n)
                         printf("    Next Try: anytime\n");
-                else {
-                        char buf[FORMAT_TIMESPAN_MAX];
+                else
                         printf("    Next Try: %sin %s%s\n",
                                ansi_highlight_red(),
-                               format_timespan(buf, sizeof(buf), t - n, USEC_PER_SEC),
+                               FORMAT_TIMESPAN(t - n, USEC_PER_SEC),
                                ansi_normal());
-                }
         }
 
-        if (storage != USER_CLASSIC) {
-                char buf[FORMAT_TIMESPAN_MAX];
+        if (storage != USER_CLASSIC)
                 printf(" Auth. Limit: %" PRIu64 " attempts per %s\n", user_record_ratelimit_burst(hr),
-                       format_timespan(buf, sizeof(buf), user_record_ratelimit_interval_usec(hr), 0));
-        }
+                       FORMAT_TIMESPAN(user_record_ratelimit_interval_usec(hr), 0));
 
         if (hr->enforce_password_policy >= 0)
                 printf(" Passwd Pol.: %s\n", yes_no(hr->enforce_password_policy));
@@ -443,24 +411,23 @@ void user_record_show(UserRecord *hr, bool show_full_group_info) {
             hr->password_change_warn_usec != UINT64_MAX ||
             hr->password_change_inactive_usec != UINT64_MAX) {
 
-                char buf[FORMAT_TIMESPAN_MAX];
                 printf(" Passwd Chg.:");
 
                 if (hr->password_change_min_usec != UINT64_MAX) {
-                        printf(" min %s", format_timespan(buf, sizeof(buf), hr->password_change_min_usec, 0));
+                        printf(" min %s", FORMAT_TIMESPAN(hr->password_change_min_usec, 0));
 
                         if (hr->password_change_max_usec != UINT64_MAX)
                                 printf(" …");
                 }
 
                 if (hr->password_change_max_usec != UINT64_MAX)
-                        printf(" max %s", format_timespan(buf, sizeof(buf), hr->password_change_max_usec, 0));
+                        printf(" max %s", FORMAT_TIMESPAN(hr->password_change_max_usec, 0));
 
                 if (hr->password_change_warn_usec != UINT64_MAX)
-                        printf("/warn %s", format_timespan(buf, sizeof(buf), hr->password_change_warn_usec, 0));
+                        printf("/warn %s", FORMAT_TIMESPAN(hr->password_change_warn_usec, 0));
 
                 if (hr->password_change_inactive_usec != UINT64_MAX)
-                        printf("/inactive %s", format_timespan(buf, sizeof(buf), hr->password_change_inactive_usec, 0));
+                        printf("/inactive %s", FORMAT_TIMESPAN(hr->password_change_inactive_usec, 0));
 
                 printf("\n");
         }
@@ -496,10 +463,8 @@ void user_record_show(UserRecord *hr, bool show_full_group_info) {
         if (hr->signed_locally >= 0)
                 printf("  Local Sig.: %s\n", yes_no(hr->signed_locally));
 
-        if (hr->stop_delay_usec != UINT64_MAX) {
-                char buf[FORMAT_TIMESPAN_MAX];
-                printf("  Stop Delay: %s\n", format_timespan(buf, sizeof(buf), hr->stop_delay_usec, 0));
-        }
+        if (hr->stop_delay_usec != UINT64_MAX)
+                printf("  Stop Delay: %s\n", FORMAT_TIMESPAN(hr->stop_delay_usec, 0));
 
         if (hr->auto_login >= 0)
                 printf("Autom. Login: %s\n", yes_no(hr->auto_login));
@@ -519,10 +484,8 @@ void group_record_show(GroupRecord *gr, bool show_full_user_info) {
 
         printf(" Disposition: %s\n", user_disposition_to_string(group_record_disposition(gr)));
 
-        if (gr->last_change_usec != USEC_INFINITY) {
-                char buf[FORMAT_TIMESTAMP_MAX];
-                printf(" Last Change: %s\n", format_timestamp(buf, sizeof(buf), gr->last_change_usec));
-        }
+        if (gr->last_change_usec != USEC_INFINITY)
+                printf(" Last Change: %s\n", FORMAT_TIMESTAMP(gr->last_change_usec));
 
         if (gid_is_valid(gr->gid))
                 printf("         GID: " GID_FMT "\n", gr->gid);
index 91ac7c38320accc8efab467d44d51ca182730350..555c71c82da80d7baab559d4f68fe1eed19e2173 100644 (file)
@@ -90,7 +90,7 @@ UserDBIterator* userdb_iterator_free(UserDBIterator *iterator) {
                 break;
 
         default:
-                assert_not_reached("Unexpected state?");
+                assert_not_reached();
         }
 
         sd_event_unref(iterator->event);
@@ -333,7 +333,7 @@ static int userdb_on_query_reply(
         }
 
         default:
-                assert_not_reached("unexpected lookup");
+                assert_not_reached();
         }
 
 finish:
index 3eeee24693ff3d87637df0bf1560e67bdafbfab2..b31cdd679ba56ab2c7e4be1c9a8e8f753f11a683 100644 (file)
@@ -340,7 +340,6 @@ int utmp_wall(
         void *userdata) {
 
         _cleanup_free_ char *text = NULL, *hn = NULL, *un = NULL, *stdin_tty = NULL;
-        char date[FORMAT_TIMESTAMP_MAX];
         struct utmpx *u;
         int r;
 
@@ -364,7 +363,7 @@ int utmp_wall(
                      "%s\r\n\r\n",
                      un ?: username, hn,
                      origin_tty ? " on " : "", strempty(origin_tty),
-                     format_timestamp(date, sizeof(date), now(CLOCK_REALTIME)),
+                     FORMAT_TIMESTAMP(now(CLOCK_REALTIME)),
                      message) < 0)
                 return -ENOMEM;
 
index 6b0b343ae92c7f31c63442c9f4fefe4f41b96a59..07a1b96f6013189536b3598ef12505204f07154b 100644 (file)
@@ -1,7 +1,7 @@
 /* SPDX-License-Identifier: LGPL-2.1-or-later */
 
 #include <malloc.h>
-#include <sys/poll.h>
+#include <poll.h>
 
 #include "alloc-util.h"
 #include "errno-util.h"
@@ -905,7 +905,7 @@ static int varlink_dispatch_method(Varlink *v) {
                 break;
 
         default:
-                assert_not_reached("Unexpected state");
+                assert_not_reached();
 
         }
 
@@ -1521,7 +1521,7 @@ int varlink_call(
                 return varlink_log_errno(v, SYNTHETIC_ERRNO(ETIME), "Connection timed out.");
 
         default:
-                assert_not_reached("Unexpected state after method call.");
+                assert_not_reached();
         }
 }
 
@@ -2145,7 +2145,9 @@ int varlink_server_add_connection(VarlinkServer *server, int fd, Varlink **ret)
                 v->ucred_acquired = true;
         }
 
-        (void) asprintf(&v->description, "%s-%i", server->description ?: "varlink", v->fd);
+        _cleanup_free_ char *desc = NULL;
+        if (asprintf(&desc, "%s-%i", server->description ?: "varlink", v->fd) >= 0)
+                v->description = TAKE_PTR(desc);
 
         /* Link up the server and the connection, and take reference in both directions. Note that the
          * reference on the connection is left dangling. It will be dropped when the connection is closed,
index d33acafe64d869b91aee402e0307ac7462e8f067..361d5837dc984b1af694ea349bc9fd809544189d 100644 (file)
@@ -32,7 +32,6 @@ static int update_timeout(void) {
                 if (ioctl(watchdog_fd, WDIOC_SETOPTIONS, &flags) < 0)
                         return log_warning_errno(errno, "Failed to disable hardware watchdog: %m");
         } else {
-                char buf[FORMAT_TIMESPAN_MAX];
                 int sec, flags;
                 usec_t t;
 
@@ -41,8 +40,7 @@ static int update_timeout(void) {
                 if (ioctl(watchdog_fd, WDIOC_SETTIMEOUT, &sec) < 0)
                         return log_warning_errno(errno, "Failed to set timeout to %is: %m", sec);
 
-                watchdog_timeout = (usec_t) sec * USEC_PER_SEC;
-                log_info("Set hardware watchdog to %s.", format_timespan(buf, sizeof(buf), watchdog_timeout, 0));
+                log_info("Set hardware watchdog to %s.", FORMAT_TIMESPAN(sec * USEC_PER_SEC, 0));
 
                 flags = WDIOS_ENABLECARD;
                 if (ioctl(watchdog_fd, WDIOC_SETOPTIONS, &flags) < 0) {
index 8ff3feafe40790a436b1f9fa7fc69b44f43cbefb..df381d85b8b9f7eaef6b496d197cf3fea7385424 100644 (file)
@@ -233,5 +233,5 @@ int xml_tokenize(const char **p, char **name, void **state, unsigned *line) {
 
         }
 
-        assert_not_reached("Bad state");
+        assert_not_reached();
 }
index a98cfc4d8ae22c73de34e20f3cf2426711ae9425..2ba1a21dae943ad833ca93844e43acac08157c3c 100644 (file)
@@ -149,7 +149,7 @@ static int parse_argv(int argc, char *argv[]) {
                         return -EINVAL;
 
                 default:
-                        assert_not_reached("Unhandled option code.");
+                        assert_not_reached();
                 }
 
         if (!arg_verb)
@@ -610,7 +610,7 @@ int main(int argc, char *argv[]) {
                 break;
 
         default:
-                assert_not_reached("Unknown magic");
+                assert_not_reached();
         }
 
         (void) reboot(cmd);
index a3aeb24633ffb3f5be72d501fb91947ae255ed27..7064f3a90594bce963a8eab0721369a57d855744 100644 (file)
@@ -266,7 +266,6 @@ static int execute(
 
 static int execute_s2h(const SleepConfig *sleep_config) {
         _cleanup_close_ int tfd = -1;
-        char buf[FORMAT_TIMESPAN_MAX];
         struct itimerspec ts = {};
         int r;
 
@@ -277,7 +276,7 @@ static int execute_s2h(const SleepConfig *sleep_config) {
                 return log_error_errno(errno, "Error creating timerfd: %m");
 
         log_debug("Set timerfd wake alarm for %s",
-                  format_timespan(buf, sizeof(buf), sleep_config->hibernate_delay_sec, USEC_PER_SEC));
+                  FORMAT_TIMESPAN(sleep_config->hibernate_delay_sec, USEC_PER_SEC));
 
         timespec_store(&ts.it_value, sleep_config->hibernate_delay_sec);
 
@@ -299,7 +298,7 @@ static int execute_s2h(const SleepConfig *sleep_config) {
 
         /* If woken up after alarm time, hibernate */
         log_debug("Attempting to hibernate after waking from %s timer",
-                  format_timespan(buf, sizeof(buf), sleep_config->hibernate_delay_sec, USEC_PER_SEC));
+                  FORMAT_TIMESPAN(sleep_config->hibernate_delay_sec, USEC_PER_SEC));
 
         r = execute(sleep_config, SLEEP_HIBERNATE, NULL);
         if (r < 0) {
@@ -366,7 +365,7 @@ static int parse_argv(int argc, char *argv[]) {
                         return -EINVAL;
 
                 default:
-                        assert_not_reached("Unhandled option");
+                        assert_not_reached();
                 }
 
         if (argc - optind != 1)
index 6e3ee0d76b00153d51476dfde6016b95af7d2fcc..be0be91f3e46f05b9a0b48b77d777c7541fe5c24 100644 (file)
@@ -657,7 +657,7 @@ static int parse_argv(int argc, char *argv[]) {
                         return -EINVAL;
 
                 default:
-                        assert_not_reached("Unhandled option");
+                        assert_not_reached();
                 }
 
         if (optind >= argc)
index 458a91be29c8e21c901c068dd4e0ff0a08c30544..8c452854b12de5c06cdb45a6bb4466c1270b594b 100644 (file)
@@ -369,7 +369,7 @@ static int parse_argv(int argc, char *argv[]) {
                         return -EINVAL;
 
                 default:
-                        assert_not_reached("Unhandled option");
+                        assert_not_reached();
                 }
 
         if (arg_cat_config && argc > optind)
index 572e4007fe27ff0072157520c70c823fbf337790..1e9279d612dd648028e1861190c0a5e62640d3c7 100644 (file)
@@ -566,7 +566,7 @@ static int merge_subprocess(Hashmap *images, const char *workspace) {
                         break;
                 }
                 default:
-                        assert_not_reached("Unsupported image type");
+                        assert_not_reached();
                 }
 
                 r = validate_version(
@@ -957,7 +957,7 @@ static int parse_argv(int argc, char *argv[]) {
                         return -EINVAL;
 
                 default:
-                        assert_not_reached("Unhandled option");
+                        assert_not_reached();
                 }
 
         return 1;
index 2a0290de7f459d90aa75748dbaec5dfba036b460..ba385ea2a2737f831d003cba5fa5fdd8092e2384 100644 (file)
@@ -34,7 +34,7 @@ int add_dependency(int argc, char *argv[], void *userdata) {
         else if (streq(verb, "add-requires"))
                 dep = UNIT_REQUIRES;
         else
-                assert_not_reached("Unknown verb");
+                assert_not_reached();
 
         if (install_client_side()) {
                 r = unit_file_add_dependency(arg_scope, unit_file_flags_from_args(), arg_root, names, target, dep, &changes, &n_changes);
index eca3a6d35490e2d1a8b43b02a74a4d164a1abf90..fb4d6435171bb75aa60e58160111e37e1927cc8c 100644 (file)
@@ -44,7 +44,7 @@ int clean_or_freeze_unit(int argc, char *argv[], void *userdata) {
         else if (streq(argv[0], "thaw"))
                 method = "ThawUnit";
         else
-                assert_not_reached("Unhandled method");
+                assert_not_reached();
 
         STRV_FOREACH(name, names) {
                 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
index 51a89ae4a737db7e8c6d9333408dc422a8c87b66..760758322f5671861f9da803a87e6fb16542c242 100644 (file)
@@ -127,7 +127,7 @@ int halt_parse_argv(int argc, char *argv[]) {
                         return -EINVAL;
 
                 default:
-                        assert_not_reached("Unhandled option");
+                        assert_not_reached();
                 }
 
         if (arg_action == ACTION_REBOOT && (argc == optind || argc == optind + 1)) {
index ad6325bf35f364e3b1bd989b8409a6038e426351..04b6b7630b95311815a58e77d261fd530a552b95 100644 (file)
@@ -55,7 +55,7 @@ int runlevel_parse_argv(int argc, char *argv[]) {
                         return -EINVAL;
 
                 default:
-                        assert_not_reached("Unhandled option");
+                        assert_not_reached();
                 }
 
         if (optind < argc)
index 11154f5f8b261858a409bb62e533432619f0c90e..5e613e2aa20ba79792d00e0aa1d7d21b8b0b4ec1 100644 (file)
@@ -112,7 +112,7 @@ int shutdown_parse_argv(int argc, char *argv[]) {
                         return -EINVAL;
 
                 default:
-                        assert_not_reached("Unhandled option");
+                        assert_not_reached();
                 }
 
         if (argc > optind && arg_action != ACTION_CANCEL_SHUTDOWN) {
index f0e9ca8d7948c922d53b869ffca424cb4cca98bb..c81e9bc3ce33a0cd6b424fd5addbb2cd7ed8588b 100644 (file)
@@ -93,7 +93,7 @@ int telinit_parse_argv(int argc, char *argv[]) {
                         return -EINVAL;
 
                 default:
-                        assert_not_reached("Unhandled option");
+                        assert_not_reached();
                 }
 
         if (optind >= argc)
index 03ba90838329f73c7309a365ccc61adef89cff6a..1c2331533795c8308a4938685abf20f2894bd76f 100644 (file)
@@ -35,7 +35,7 @@ int daemon_reload(int argc, char *argv[], void *userdata) {
                 break;
 
         default:
-                assert_not_reached("Unexpected action");
+                assert_not_reached();
         }
 
         r = bus_message_new_method_call(bus, &m, bus_systemd_mgr, method);
index 8f053ca649c71eb08c422b6df7a62fce0a602e9d..dcbe2c730218d6b709fc55847207cb780cb3a896 100644 (file)
@@ -124,7 +124,7 @@ int enable_unit(int argc, char *argv[], void *userdata) {
                 else if (streq(verb, "revert"))
                         r = unit_file_revert(arg_scope, arg_root, names, &changes, &n_changes);
                 else
-                        assert_not_reached("Unknown verb");
+                        assert_not_reached();
 
                 unit_file_dump_changes(r, verb, changes, n_changes, arg_quiet);
                 if (r < 0)
@@ -191,7 +191,7 @@ int enable_unit(int argc, char *argv[], void *userdata) {
                         method = "RevertUnitFiles";
                         send_runtime = send_force = false;
                 } else
-                        assert_not_reached("Unknown verb");
+                        assert_not_reached();
 
                 r = bus_message_new_method_call(bus, &m, bus_systemd_mgr, method);
                 if (r < 0)
index 28dd25b523dffb5e6d0887e39cbaaef9be1aa775..b1c0e13f2cd716bbf90f3e9392e33b4956800371 100644 (file)
@@ -296,7 +296,6 @@ int logind_schedule_shutdown(void) {
 
 #if ENABLE_LOGIND
         _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
-        char date[FORMAT_TIMESTAMP_MAX];
         const char *action;
         const char *log_action;
         sd_bus *bus;
@@ -340,7 +339,9 @@ int logind_schedule_shutdown(void) {
                 return log_warning_errno(r, "Failed to call ScheduleShutdown in logind, proceeding with immediate shutdown: %s", bus_error_message(&error, r));
 
         if (!arg_quiet)
-                log_info("%s scheduled for %s, use 'shutdown -c' to cancel.", log_action, format_timestamp_style(date, sizeof(date), arg_when, arg_timestamp_style));
+                log_info("%s scheduled for %s, use 'shutdown -c' to cancel.",
+                         log_action,
+                         FORMAT_TIMESTAMP_STYLE(arg_when, arg_timestamp_style));
         return 0;
 #else
         return log_error_errno(SYNTHETIC_ERRNO(ENOSYS),
index 183a7b6a8ad650182dad5ce7f8b0246385149c58..5739bac070a2f98f9e07ce710db18a0087a1ed70 100644 (file)
@@ -6,33 +6,20 @@
 #include "systemctl-util.h"
 #include "systemctl.h"
 
-int set_property(int argc, char *argv[], void *userdata) {
-        _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL;
+static int set_property_one(sd_bus *bus, const char *name, char **properties) {
         _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
-        _cleanup_free_ char *n = NULL;
-        UnitType t;
-        sd_bus *bus;
+        _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL;
         int r;
 
-        r = acquire_bus(BUS_MANAGER, &bus);
-        if (r < 0)
-                return r;
-
-        polkit_agent_open_maybe();
-
         r = bus_message_new_method_call(bus, &m, bus_systemd_mgr, "SetUnitProperties");
         if (r < 0)
                 return bus_log_create_error(r);
 
-        r = unit_name_mangle(argv[1], arg_quiet ? 0 : UNIT_NAME_MANGLE_WARN, &n);
-        if (r < 0)
-                return log_error_errno(r, "Failed to mangle unit name: %m");
-
-        t = unit_name_to_type(n);
+        UnitType t = unit_name_to_type(name);
         if (t < 0)
-                return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Invalid unit type: %s", n);
+                return log_error_errno(t, "Invalid unit type: %s", name);
 
-        r = sd_bus_message_append(m, "sb", n, arg_runtime);
+        r = sd_bus_message_append(m, "sb", name, arg_runtime);
         if (r < 0)
                 return bus_log_create_error(r);
 
@@ -40,7 +27,7 @@ int set_property(int argc, char *argv[], void *userdata) {
         if (r < 0)
                 return bus_log_create_error(r);
 
-        r = bus_append_unit_property_assignment_many(m, t, strv_skip(argv, 2));
+        r = bus_append_unit_property_assignment_many(m, t, properties);
         if (r < 0)
                 return r;
 
@@ -50,7 +37,33 @@ int set_property(int argc, char *argv[], void *userdata) {
 
         r = sd_bus_call(bus, m, 0, &error, NULL);
         if (r < 0)
-                return log_error_errno(r, "Failed to set unit properties on %s: %s", n, bus_error_message(&error, r));
+                return log_error_errno(r, "Failed to set unit properties on %s: %s",
+                                       name, bus_error_message(&error, r));
 
         return 0;
 }
+
+int set_property(int argc, char *argv[], void *userdata) {
+        sd_bus *bus;
+        _cleanup_strv_free_ char **names = NULL;
+        char **name;
+        int r, k;
+
+        r = acquire_bus(BUS_MANAGER, &bus);
+        if (r < 0)
+                return r;
+
+        polkit_agent_open_maybe();
+
+        r = expand_unit_names(bus, STRV_MAKE(argv[1]), NULL, &names, NULL);
+        if (r < 0)
+                return log_error_errno(r, "Failed to expand '%s' into names: %m", argv[1]);
+
+        r = 0;
+        STRV_FOREACH(name, names) {
+                k = set_property_one(bus, *name, strv_skip(argv, 2));
+                if (k < 0 && r >= 0)
+                        r = k;
+        }
+        return r;
+}
index 470ff617d603935cf3a82ca354c0971c97b07a74..b325d44c5ea85080c0121bca183828d4bb5157dc 100644 (file)
@@ -300,8 +300,7 @@ static void print_status_info(
                 UnitStatusInfo *i,
                 bool *ellipsized) {
 
-        char since1[FORMAT_TIMESTAMP_RELATIVE_MAX], since2[FORMAT_TIMESTAMP_MAX];
-        const char *s1, *s2, *active_on, *active_off, *on, *off, *ss, *fs;
+        const char *active_on, *active_off, *on, *off, *ss, *fs;
         _cleanup_free_ char *formatted_path = NULL;
         ExecStatusInfo *p;
         usec_t timestamp;
@@ -419,13 +418,10 @@ static void print_status_info(
                     STRPTR_IN_SET(i->active_state, "activating")          ? i->inactive_exit_timestamp :
                                                                             i->active_exit_timestamp;
 
-        s1 = format_timestamp_relative(since1, sizeof(since1), timestamp);
-        s2 = format_timestamp_style(since2, sizeof(since2), timestamp, arg_timestamp_style);
-
-        if (s1)
-                printf(" since %s; %s\n", s2, s1);
-        else if (s2)
-                printf(" since %s\n", s2);
+        if (timestamp > 0 && timestamp < USEC_INFINITY)
+                printf(" since %s; %s\n",
+                       FORMAT_TIMESTAMP_STYLE(timestamp, arg_timestamp_style),
+                       FORMAT_TIMESTAMP_RELATIVE(timestamp));
         else
                 printf("\n");
 
@@ -442,24 +438,18 @@ static void print_status_info(
         }
 
         if (endswith(i->id, ".timer")) {
-                char tstamp1[FORMAT_TIMESTAMP_RELATIVE_MAX],
-                     tstamp2[FORMAT_TIMESTAMP_MAX];
-                const char *next_rel_time, *next_time;
-                dual_timestamp nw, next = {i->next_elapse_real,
-                                           i->next_elapse_monotonic};
+                dual_timestamp nw, next = {i->next_elapse_real, i->next_elapse_monotonic};
                 usec_t next_elapse;
 
-                printf("    Trigger: ");
-
                 dual_timestamp_get(&nw);
                 next_elapse = calc_next_elapse(&nw, &next);
-                next_rel_time = format_timestamp_relative(tstamp1, sizeof tstamp1, next_elapse);
-                next_time = format_timestamp_style(tstamp2, sizeof tstamp2, next_elapse, arg_timestamp_style);
 
-                if (next_time && next_rel_time)
-                        printf("%s; %s\n", next_time, next_rel_time);
+                if (next_elapse > 0 && next_elapse < USEC_INFINITY)
+                        printf("    Trigger: %s; %s\n",
+                               FORMAT_TIMESTAMP_STYLE(next_elapse, arg_timestamp_style),
+                               FORMAT_TIMESTAMP_RELATIVE(next_elapse));
                 else
-                        printf("n/a\n");
+                        printf("    Trigger: n/a\n");
         }
 
         STRV_FOREACH(t, i->triggers) {
@@ -478,12 +468,10 @@ static void print_status_info(
                 UnitCondition *c;
                 int n = 0;
 
-                s1 = format_timestamp_relative(since1, sizeof(since1), i->condition_timestamp);
-                s2 = format_timestamp_style(since2, sizeof(since2), i->condition_timestamp, arg_timestamp_style);
-
-                printf("  Condition: start %scondition failed%s at %s%s%s\n",
+                printf("  Condition: start %scondition failed%s at %s; %s\n",
                        ansi_highlight_yellow(), ansi_normal(),
-                       s2, s1 ? "; " : "", strempty(s1));
+                       FORMAT_TIMESTAMP_STYLE(i->condition_timestamp, arg_timestamp_style),
+                       FORMAT_TIMESTAMP_RELATIVE(i->condition_timestamp));
 
                 LIST_FOREACH(conditions, c, i->conditions)
                         if (c->tristate < 0)
@@ -500,12 +488,10 @@ static void print_status_info(
         }
 
         if (!i->assert_result && i->assert_timestamp > 0) {
-                s1 = format_timestamp_relative(since1, sizeof(since1), i->assert_timestamp);
-                s2 = format_timestamp_style(since2, sizeof(since2), i->assert_timestamp, arg_timestamp_style);
-
-                printf("     Assert: start %sassertion failed%s at %s%s%s\n",
+                printf("     Assert: start %sassertion failed%s at %s; %s\n",
                        ansi_highlight_red(), ansi_normal(),
-                       s2, s1 ? "; " : "", strempty(s1));
+                       FORMAT_TIMESTAMP_STYLE(i->assert_timestamp, arg_timestamp_style),
+                       FORMAT_TIMESTAMP_RELATIVE(i->assert_timestamp));
                 if (i->failed_assert_trigger)
                         printf("             none of the trigger assertions were met\n");
                 else if (i->failed_assert)
@@ -651,21 +637,15 @@ static void print_status_info(
         if (i->status_errno > 0)
                 printf("      Error: %i (%s)\n", i->status_errno, strerror_safe(i->status_errno));
 
-        if (i->ip_ingress_bytes != UINT64_MAX && i->ip_egress_bytes != UINT64_MAX) {
-                char buf_in[FORMAT_BYTES_MAX], buf_out[FORMAT_BYTES_MAX];
-
+        if (i->ip_ingress_bytes != UINT64_MAX && i->ip_egress_bytes != UINT64_MAX)
                 printf("         IP: %s in, %s out\n",
-                        format_bytes(buf_in, sizeof(buf_in), i->ip_ingress_bytes),
-                        format_bytes(buf_out, sizeof(buf_out), i->ip_egress_bytes));
-        }
-
-        if (i->io_read_bytes != UINT64_MAX && i->io_write_bytes != UINT64_MAX) {
-                char buf_in[FORMAT_BYTES_MAX], buf_out[FORMAT_BYTES_MAX];
+                       FORMAT_BYTES(i->ip_ingress_bytes),
+                       FORMAT_BYTES(i->ip_egress_bytes));
 
+        if (i->io_read_bytes != UINT64_MAX && i->io_write_bytes != UINT64_MAX)
                 printf("         IO: %s read, %s written\n",
-                        format_bytes(buf_in, sizeof(buf_in), i->io_read_bytes),
-                        format_bytes(buf_out, sizeof(buf_out), i->io_write_bytes));
-        }
+                        FORMAT_BYTES(i->io_read_bytes),
+                        FORMAT_BYTES(i->io_write_bytes));
 
         if (i->tasks_current != UINT64_MAX) {
                 printf("      Tasks: %" PRIu64, i->tasks_current);
@@ -677,9 +657,7 @@ static void print_status_info(
         }
 
         if (i->memory_current != UINT64_MAX) {
-                char buf[FORMAT_BYTES_MAX];
-
-                printf("     Memory: %s", format_bytes(buf, sizeof(buf), i->memory_current));
+                printf("     Memory: %s", FORMAT_BYTES(i->memory_current));
 
                 if (i->memory_min > 0 || i->memory_low > 0 ||
                     i->memory_high != CGROUP_LIMIT_MAX || i->memory_max != CGROUP_LIMIT_MAX ||
@@ -690,31 +668,31 @@ static void print_status_info(
 
                         printf(" (");
                         if (i->memory_min > 0) {
-                                printf("%smin: %s", prefix, format_bytes_cgroup_protection(buf, sizeof(buf), i->memory_min));
+                                printf("%smin: %s", prefix, FORMAT_BYTES_CGROUP_PROTECTION(i->memory_min));
                                 prefix = " ";
                         }
                         if (i->memory_low > 0) {
-                                printf("%slow: %s", prefix, format_bytes_cgroup_protection(buf, sizeof(buf), i->memory_low));
+                                printf("%slow: %s", prefix, FORMAT_BYTES_CGROUP_PROTECTION(i->memory_low));
                                 prefix = " ";
                         }
                         if (i->memory_high != CGROUP_LIMIT_MAX) {
-                                printf("%shigh: %s", prefix, format_bytes(buf, sizeof(buf), i->memory_high));
+                                printf("%shigh: %s", prefix, FORMAT_BYTES(i->memory_high));
                                 prefix = " ";
                         }
                         if (i->memory_max != CGROUP_LIMIT_MAX) {
-                                printf("%smax: %s", prefix, format_bytes(buf, sizeof(buf), i->memory_max));
+                                printf("%smax: %s", prefix, FORMAT_BYTES(i->memory_max));
                                 prefix = " ";
                         }
                         if (i->memory_swap_max != CGROUP_LIMIT_MAX) {
-                                printf("%sswap max: %s", prefix, format_bytes(buf, sizeof(buf), i->memory_swap_max));
+                                printf("%sswap max: %s", prefix, FORMAT_BYTES(i->memory_swap_max));
                                 prefix = " ";
                         }
                         if (i->memory_limit != CGROUP_LIMIT_MAX) {
-                                printf("%slimit: %s", prefix, format_bytes(buf, sizeof(buf), i->memory_limit));
+                                printf("%slimit: %s", prefix, FORMAT_BYTES(i->memory_limit));
                                 prefix = " ";
                         }
                         if (i->memory_available != CGROUP_LIMIT_MAX) {
-                                printf("%savailable: %s", prefix, format_bytes(buf, sizeof(buf), i->memory_available));
+                                printf("%savailable: %s", prefix, FORMAT_BYTES(i->memory_available));
                                 prefix = " ";
                         }
                         printf(")");
@@ -722,10 +700,8 @@ static void print_status_info(
                 printf("\n");
         }
 
-        if (i->cpu_usage_nsec != UINT64_MAX) {
-                char buf[FORMAT_TIMESPAN_MAX];
-                printf("        CPU: %s\n", format_timespan(buf, sizeof(buf), i->cpu_usage_nsec / NSEC_PER_USEC, USEC_PER_MSEC));
-        }
+        if (i->cpu_usage_nsec != UINT64_MAX)
+                printf("        CPU: %s\n", FORMAT_TIMESPAN(i->cpu_usage_nsec / NSEC_PER_USEC, USEC_PER_MSEC));
 
         if (i->control_group) {
                 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
@@ -1235,15 +1211,12 @@ static int print_property(const char *name, const char *expected_value, sd_bus_m
                         if (r < 0)
                                 return bus_log_parse_error(r);
 
-                        while ((r = sd_bus_message_read(m, "(stt)", &base, &v, &next_elapse)) > 0) {
-                                char timespan1[FORMAT_TIMESPAN_MAX] = "n/a", timespan2[FORMAT_TIMESPAN_MAX] = "n/a";
-
-                                (void) format_timespan(timespan1, sizeof timespan1, v, 0);
-                                (void) format_timespan(timespan2, sizeof timespan2, next_elapse, 0);
-
+                        while ((r = sd_bus_message_read(m, "(stt)", &base, &v, &next_elapse)) > 0)
                                 bus_print_property_valuef(name, expected_value, flags,
-                                                          "{ %s=%s ; next_elapse=%s }", base, timespan1, timespan2);
-                        }
+                                                          "{ %s=%s ; next_elapse=%s }",
+                                                          base,
+                                                          strna(FORMAT_TIMESPAN(v, 0)),
+                                                          strna(FORMAT_TIMESPAN(next_elapse, 0)));
                         if (r < 0)
                                 return bus_log_parse_error(r);
 
@@ -1261,13 +1234,10 @@ static int print_property(const char *name, const char *expected_value, sd_bus_m
                         if (r < 0)
                                 return bus_log_parse_error(r);
 
-                        while ((r = sd_bus_message_read(m, "(sst)", &base, &spec, &next_elapse)) > 0) {
-                                char timestamp[FORMAT_TIMESTAMP_MAX] = "n/a";
-
-                                (void) format_timestamp_style(timestamp, sizeof(timestamp), next_elapse, arg_timestamp_style);
+                        while ((r = sd_bus_message_read(m, "(sst)", &base, &spec, &next_elapse)) > 0)
                                 bus_print_property_valuef(name, expected_value, flags,
-                                                          "{ %s=%s ; next_elapse=%s }", base, spec, timestamp);
-                        }
+                                                          "{ %s=%s ; next_elapse=%s }", base, spec,
+                                                          FORMAT_TIMESTAMP_STYLE(next_elapse, arg_timestamp_style));
                         if (r < 0)
                                 return bus_log_parse_error(r);
 
@@ -1286,7 +1256,6 @@ static int print_property(const char *name, const char *expected_value, sd_bus_m
                                 return bus_log_parse_error(r);
 
                         while ((r = exec_status_info_deserialize(m, &info, is_ex_prop)) > 0) {
-                                char timestamp1[FORMAT_TIMESTAMP_MAX], timestamp2[FORMAT_TIMESTAMP_MAX];
                                 _cleanup_strv_free_ char **optv = NULL;
                                 _cleanup_free_ char *tt = NULL, *o = NULL;
 
@@ -1304,8 +1273,8 @@ static int print_property(const char *name, const char *expected_value, sd_bus_m
                                                                   strna(info.path),
                                                                   strna(tt),
                                                                   strna(o),
-                                                                  strna(format_timestamp_style(timestamp1, sizeof(timestamp1), info.start_timestamp, arg_timestamp_style)),
-                                                                  strna(format_timestamp_style(timestamp2, sizeof(timestamp2), info.exit_timestamp, arg_timestamp_style)),
+                                                                  strna(FORMAT_TIMESTAMP_STYLE(info.start_timestamp, arg_timestamp_style)),
+                                                                  strna(FORMAT_TIMESTAMP_STYLE(info.exit_timestamp, arg_timestamp_style)),
                                                                   info.pid,
                                                                   sigchld_code_to_string(info.code),
                                                                   info.status,
@@ -1317,8 +1286,8 @@ static int print_property(const char *name, const char *expected_value, sd_bus_m
                                                                   strna(info.path),
                                                                   strna(tt),
                                                                   yes_no(info.ignore),
-                                                                  strna(format_timestamp_style(timestamp1, sizeof(timestamp1), info.start_timestamp, arg_timestamp_style)),
-                                                                  strna(format_timestamp_style(timestamp2, sizeof(timestamp2), info.exit_timestamp, arg_timestamp_style)),
+                                                                  strna(FORMAT_TIMESTAMP_STYLE(info.start_timestamp, arg_timestamp_style)),
+                                                                  strna(FORMAT_TIMESTAMP_STYLE(info.exit_timestamp, arg_timestamp_style)),
                                                                   info.pid,
                                                                   sigchld_code_to_string(info.code),
                                                                   info.status,
@@ -1397,7 +1366,6 @@ static int print_property(const char *name, const char *expected_value, sd_bus_m
 
                 }  else if (contents[0] == SD_BUS_TYPE_STRUCT_BEGIN &&
                             streq(name, "IODeviceLatencyTargetUSec")) {
-                        char ts[FORMAT_TIMESPAN_MAX];
                         const char *path;
                         uint64_t target;
 
@@ -1407,7 +1375,7 @@ static int print_property(const char *name, const char *expected_value, sd_bus_m
 
                         while ((r = sd_bus_message_read(m, "(st)", &path, &target)) > 0)
                                 bus_print_property_valuef(name, expected_value, flags, "%s %s", strna(path),
-                                                          format_timespan(ts, sizeof(ts), target, 1));
+                                                          FORMAT_TIMESPAN(target, 1));
                         if (r < 0)
                                 return bus_log_parse_error(r);
 
@@ -1915,7 +1883,7 @@ static int show_one(
                 return log_error_errno(r, "Failed to get properties: %s", bus_error_message(&error, r));
 
         if (unit && streq_ptr(info.load_state, "not-found") && streq_ptr(info.active_state, "inactive")) {
-                log_full(show_mode == SYSTEMCTL_SHOW_STATUS ? LOG_ERR : LOG_DEBUG,
+                log_full(show_mode == SYSTEMCTL_SHOW_PROPERTIES ? LOG_DEBUG : LOG_ERR,
                          "Unit %s could not be found.", unit);
 
                 if (show_mode == SYSTEMCTL_SHOW_STATUS)
@@ -2021,7 +1989,6 @@ static int show_all(
 }
 
 static int show_system_status(sd_bus *bus) {
-        char since1[FORMAT_TIMESTAMP_RELATIVE_MAX], since2[FORMAT_TIMESTAMP_MAX];
         _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
         _cleanup_(machine_info_clear) struct machine_info mi = {};
         _cleanup_free_ char *hn = NULL;
@@ -2064,8 +2031,8 @@ static int show_system_status(sd_bus *bus) {
         printf("   Failed: %" PRIu32 " units\n", mi.n_failed_units);
 
         printf("    Since: %s; %s\n",
-               format_timestamp_style(since2, sizeof(since2), mi.timestamp, arg_timestamp_style),
-               format_timestamp_relative(since1, sizeof(since1), mi.timestamp));
+               FORMAT_TIMESTAMP_STYLE(mi.timestamp, arg_timestamp_style),
+               FORMAT_TIMESTAMP_RELATIVE(mi.timestamp));
 
         printf("   CGroup: %s\n", mi.control_group ?: "/");
         if (IN_SET(arg_transport,
index 3edb65be617181b3b879ced38ad0fd69d99fb141..56068d25f58c80c8170aaffc9226b5eafdb23bd7 100644 (file)
@@ -36,7 +36,7 @@ static int load_kexec_kernel(void) {
                 return log_error_errno(r,
                                        "No kexec kernel loaded and autodetection failed.\n%s",
                                        is_efi_boot()
-                                       ? "Cannot automatically load kernel: ESP partition mount point not found."
+                                       ? "Cannot automatically load kernel: ESP mount point not found."
                                        : "Automatic loading works only on systems booted with EFI.");
         if (r < 0)
                 return r;
index 99f1394bcfa631382ad73fe0e2c7640e8bc71bca..9f3174d106d21bac0bc67a0d761c24fc6547ec10 100644 (file)
@@ -930,6 +930,6 @@ int halt_now(enum action a) {
                                              (arg_dry_run ? REBOOT_DRY_RUN : 0));
 
         default:
-                assert_not_reached("Unknown action.");
+                assert_not_reached();
         }
 }
index 4cc723aab5e49394af9855be36044a21542e8d7e..f5ecc1f60f37e97f372b1f162b4a67205e871710 100644 (file)
@@ -922,7 +922,7 @@ static int systemctl_parse_argv(int argc, char *argv[]) {
                         return -EINVAL;
 
                 default:
-                        assert_not_reached("Unhandled option");
+                        assert_not_reached();
                 }
 
         if (arg_transport == BUS_TRANSPORT_REMOTE && arg_scope != UNIT_FILE_SYSTEM)
@@ -1184,7 +1184,7 @@ static int run(int argc, char *argv[]) {
 
         case _ACTION_INVALID:
         default:
-                assert_not_reached("Unknown action");
+                assert_not_reached();
         }
 
 finish:
index e01281f4547b09215752ebe89f66f22e68ec1d01..6cae6a5767c3ee794ceb70d3f0226a30b3522abf 100644 (file)
@@ -77,7 +77,7 @@ foreach header : _systemd_headers + _not_installed_headers + [libudev_h_path]
                              check_compilation_sh,
                              args : cc.cmd_array() + ['-c', '-x'] + opt +
                                     ['-Werror', '-include',
-                                     join_paths(meson.current_source_dir(), header)])
+                                     meson.current_source_dir() / header])
                 endif
         endforeach
 endforeach
index 75f884836036def30f09efe5d2a7d0ed0da9f444..8b316fac5ac61e07c13f822024eb5c5cc4b76f15 100644 (file)
@@ -75,6 +75,12 @@ struct sd_bus_vtable {
                         uint64_t features;
                         const unsigned *vtable_format_reference;
                 } start;
+                struct {
+                        /* This field exists only to make sure we have something to initialize in
+                         * SD_BUS_VTABLE_END in a way that is both compatible with pedantic versions of C and
+                         * C++. It's unused otherwise. */
+                        size_t _reserved;
+                } end;
                 struct {
                         const char *member;
                         const char *signature;
@@ -103,11 +109,11 @@ struct sd_bus_vtable {
                 .type = _SD_BUS_VTABLE_START,                           \
                 .flags = _flags,                                        \
                 .x = {                                                  \
-                    .start = {                                          \
-                        .element_size = sizeof(sd_bus_vtable),          \
-                        .features = _SD_BUS_VTABLE_PARAM_NAMES,         \
-                        .vtable_format_reference = &sd_bus_object_vtable_format, \
-                    },                                                  \
+                        .start = {                                      \
+                                .element_size = sizeof(sd_bus_vtable),  \
+                                .features = _SD_BUS_VTABLE_PARAM_NAMES, \
+                                .vtable_format_reference = &sd_bus_object_vtable_format, \
+                        },                                              \
                 },                                                      \
         }
 
@@ -119,14 +125,14 @@ struct sd_bus_vtable {
                 .type = _SD_BUS_VTABLE_METHOD,                          \
                 .flags = _flags,                                        \
                 .x = {                                                  \
-                    .method = {                                         \
-                        .member = _member,                              \
-                        .signature = _signature,                        \
-                        .result = _result,                              \
-                        .handler = _handler,                            \
-                        .offset = _offset,                              \
-                        .names = _in_names _out_names,                  \
-                    },                                                  \
+                        .method = {                                     \
+                                .member = _member,                      \
+                                .signature = _signature,                \
+                                .result = _result,                      \
+                                .handler = _handler,                    \
+                                .offset = _offset,                      \
+                                .names = _in_names _out_names,          \
+                        },                                              \
                 },                                                      \
         }
 #define SD_BUS_METHOD_WITH_OFFSET(_member, _signature, _result, _handler, _offset, _flags)   \
@@ -141,14 +147,14 @@ struct sd_bus_vtable {
                 .type = _SD_BUS_VTABLE_SIGNAL,                          \
                 .flags = _flags,                                        \
                 .x = {                                                  \
-                    .signal = {                                         \
-                        .member = _member,                              \
-                        .signature = _signature,                        \
-                        .names = _out_names,                            \
-                    },                                                  \
+                        .signal = {                                     \
+                                .member = _member,                      \
+                                .signature = _signature,                \
+                                .names = _out_names,                    \
+                        },                                              \
                 },                                                      \
-        }
-#define SD_BUS_SIGNAL(_member, _signature, _flags)   \
+                        }
+#define SD_BUS_SIGNAL(_member, _signature, _flags)                      \
         SD_BUS_SIGNAL_WITH_NAMES(_member, _signature, "", _flags)
 
 #define SD_BUS_PROPERTY(_member, _signature, _get, _offset, _flags)     \
@@ -156,13 +162,13 @@ struct sd_bus_vtable {
                 .type = _SD_BUS_VTABLE_PROPERTY,                        \
                 .flags = _flags,                                        \
                 .x = {                                                  \
-                    .property = {                                       \
-                        .member = _member,                              \
-                        .signature = _signature,                        \
-                        .get = _get,                                    \
-                        .set = NULL,                                    \
-                        .offset = _offset,                              \
-                    },                                                  \
+                        .property = {                                   \
+                                .member = _member,                      \
+                                .signature = _signature,                \
+                                .get = _get,                            \
+                                .set = NULL,                            \
+                                .offset = _offset,                      \
+                        },                                              \
                 },                                                      \
         }
 
@@ -171,13 +177,13 @@ struct sd_bus_vtable {
                 .type = _SD_BUS_VTABLE_WRITABLE_PROPERTY,               \
                 .flags = _flags,                                        \
                 .x = {                                                  \
-                    .property = {                                       \
-                        .member = _member,                              \
-                        .signature = _signature,                        \
-                        .get = _get,                                    \
-                        .set = _set,                                    \
-                        .offset = _offset,                              \
-                    },                                                  \
+                        .property = {                                   \
+                                .member = _member,                      \
+                                .signature = _signature,                \
+                                .get = _get,                            \
+                                .set = _set,                            \
+                                .offset = _offset,                      \
+                        },                                              \
                 },                                                      \
         }
 
@@ -185,7 +191,11 @@ struct sd_bus_vtable {
         {                                                               \
                 .type = _SD_BUS_VTABLE_END,                             \
                 .flags = 0,                                             \
-                .x = { { 0 } },                                         \
+                .x = {                                                  \
+                        .end = {                                        \
+                                ._reserved = 0,                         \
+                        },                                              \
+                },                                                      \
         }
 
 #define _SD_ECHO(X) X
index a18634d2549d60e457de1ceed0b648389ab3947b..7daebdbe554feaa74280729797d39ccfdee9790a 100644 (file)
@@ -1345,7 +1345,7 @@ static int process_item(Item *i) {
                 return add_group(i);
 
         default:
-                assert_not_reached("Unknown item type");
+                assert_not_reached();
         }
 }
 
@@ -1917,7 +1917,7 @@ static int parse_argv(int argc, char *argv[]) {
                         return -EINVAL;
 
                 default:
-                        assert_not_reached("Unhandled option");
+                        assert_not_reached();
                 }
 
         if (arg_replace && arg_cat_config)
index e106059182c7b448dfb4588b7b54129fc2df2471..e9204b150d0ac9f96ebb07ebbeaab250c59a4b55 100644 (file)
@@ -15,7 +15,7 @@ path = run_command(sh, '-c', 'echo "$PATH"').stdout().strip()
 test_env = environment()
 test_env.set('SYSTEMD_KBD_MODEL_MAP', kbd_model_map)
 test_env.set('SYSTEMD_LANGUAGE_FALLBACK_MAP', language_fallback_map)
-test_env.set('PATH', '@0@:@1@'.format(meson.build_root(), path))
+test_env.set('PATH', project_build_root + ':' + path)
 
 ############################################################
 
@@ -44,6 +44,8 @@ test_dlopen_c = files('test-dlopen.c')
 tests += [
         [['src/test/test-device-nodes.c']],
 
+        [['src/test/test-ether-addr-util.c']],
+
         [['src/test/test-engine.c'],
          [libcore,
           libshared],
@@ -248,6 +250,8 @@ tests += [
 
         [['src/test/test-sysctl-util.c']],
 
+        [['src/test/test-import-util.c']],
+
         [['src/test/test-user-record.c']],
 
         [['src/test/test-user-util.c']],
index 42922a35007da5d1e3a77c1623d5ecf531816e96..655b823c7fbf646d0b29aeaf3c063186b2023fd8 100644 (file)
@@ -46,7 +46,7 @@ int main(int argc, const char *argv[]) {
         bitmap_unset(b, 32);
 
         BITMAP_FOREACH(n, NULL)
-                assert_not_reached("NULL bitmap");
+                assert_not_reached();
 
         assert_se(bitmap_set(b, 0) == 0);
         assert_se(bitmap_set(b, 1) == 0);
index ae5b5821f0fa822ba2553939d67fb97579dcca0c..23155b2d98b61580bf2a3208d97c90214a1cea8b 100644 (file)
@@ -11,7 +11,6 @@
 #include "util.h"
 
 static int test_acpi_fpdt(void) {
-        char ts_start[FORMAT_TIMESPAN_MAX], ts_exit[FORMAT_TIMESPAN_MAX], ts_span[FORMAT_TIMESPAN_MAX];
         usec_t loader_start, loader_exit;
         int r;
 
@@ -24,14 +23,13 @@ static int test_acpi_fpdt(void) {
         }
 
         log_info("ACPI FPDT: loader start=%s exit=%s duration=%s",
-                 format_timespan(ts_start, sizeof(ts_start), loader_start, USEC_PER_MSEC),
-                 format_timespan(ts_exit, sizeof(ts_exit), loader_exit, USEC_PER_MSEC),
-                 format_timespan(ts_span, sizeof(ts_span), loader_exit - loader_start, USEC_PER_MSEC));
+                 FORMAT_TIMESPAN(loader_start, USEC_PER_MSEC),
+                 FORMAT_TIMESPAN(loader_exit, USEC_PER_MSEC),
+                 FORMAT_TIMESPAN(loader_exit - loader_start, USEC_PER_MSEC));
         return 1;
 }
 
 static int test_efi_loader(void) {
-        char ts_start[FORMAT_TIMESPAN_MAX], ts_exit[FORMAT_TIMESPAN_MAX], ts_span[FORMAT_TIMESPAN_MAX];
         usec_t loader_start, loader_exit;
         int r;
 
@@ -44,14 +42,13 @@ static int test_efi_loader(void) {
         }
 
         log_info("EFI Loader: start=%s exit=%s duration=%s",
-                 format_timespan(ts_start, sizeof(ts_start), loader_start, USEC_PER_MSEC),
-                 format_timespan(ts_exit, sizeof(ts_exit), loader_exit, USEC_PER_MSEC),
-                 format_timespan(ts_span, sizeof(ts_span), loader_exit - loader_start, USEC_PER_MSEC));
+                 FORMAT_TIMESPAN(loader_start, USEC_PER_MSEC),
+                 FORMAT_TIMESPAN(loader_exit, USEC_PER_MSEC),
+                 FORMAT_TIMESPAN(loader_exit - loader_start, USEC_PER_MSEC));
         return 1;
 }
 
 static int test_boot_timestamps(void) {
-        char s[MAX(FORMAT_TIMESPAN_MAX, FORMAT_TIMESTAMP_MAX)];
         dual_timestamp fw, l, k;
         int r;
 
@@ -65,11 +62,11 @@ static int test_boot_timestamps(void) {
                 return ok ? 0 : r;
         }
 
-        log_info("Firmware began %s before kernel.", format_timespan(s, sizeof(s), fw.monotonic, 0));
-        log_info("Loader began %s before kernel.", format_timespan(s, sizeof(s), l.monotonic, 0));
-        log_info("Firmware began %s.", format_timestamp(s, sizeof(s), fw.realtime));
-        log_info("Loader began %s.", format_timestamp(s, sizeof(s), l.realtime));
-        log_info("Kernel began %s.", format_timestamp(s, sizeof(s), k.realtime));
+        log_info("Firmware began %s before kernel.", FORMAT_TIMESPAN(fw.monotonic, 0));
+        log_info("Loader began %s before kernel.", FORMAT_TIMESPAN(l.monotonic, 0));
+        log_info("Firmware began %s.", FORMAT_TIMESTAMP(fw.realtime));
+        log_info("Loader began %s.", FORMAT_TIMESTAMP(l.realtime));
+        log_info("Kernel began %s.", FORMAT_TIMESTAMP(k.realtime));
         return 1;
 }
 
index e840536d4b37273f10e87baf9bb944d68cd36ab6..77ec80190313556a3ab7c5edc81c82b73f543acb 100644 (file)
@@ -18,14 +18,13 @@ int main(int argc, char *argv[]) {
         if (fd < 0)
                 log_error_errno(errno, "Failed to open root directory: %m");
         else {
-                char ts[FORMAT_TIMESTAMP_MAX], bs[FORMAT_BYTES_MAX];
                 BtrfsSubvolInfo info;
 
                 r = btrfs_subvol_get_info_fd(fd, 0, &info);
                 if (r < 0)
                         log_error_errno(r, "Failed to get subvolume info: %m");
                 else {
-                        log_info("otime: %s", format_timestamp(ts, sizeof(ts), info.otime));
+                        log_info("otime: %s", FORMAT_TIMESTAMP(info.otime));
                         log_info("read-only (search): %s", yes_no(info.read_only));
                 }
 
@@ -33,10 +32,10 @@ int main(int argc, char *argv[]) {
                 if (r < 0)
                         log_error_errno(r, "Failed to get quota info: %m");
                 else {
-                        log_info("referenced: %s", strna(format_bytes(bs, sizeof(bs), quota.referenced)));
-                        log_info("exclusive: %s", strna(format_bytes(bs, sizeof(bs), quota.exclusive)));
-                        log_info("referenced_max: %s", strna(format_bytes(bs, sizeof(bs), quota.referenced_max)));
-                        log_info("exclusive_max: %s", strna(format_bytes(bs, sizeof(bs), quota.exclusive_max)));
+                        log_info("referenced: %s", strna(FORMAT_BYTES(quota.referenced)));
+                        log_info("exclusive: %s", strna(FORMAT_BYTES(quota.exclusive)));
+                        log_info("referenced_max: %s", strna(FORMAT_BYTES(quota.referenced_max)));
+                        log_info("exclusive_max: %s", strna(FORMAT_BYTES(quota.exclusive_max)));
                 }
 
                 r = btrfs_subvol_get_read_only_fd(fd);
index 4f1d0f64d5772f3353aee98b4a87810f2bab0e5d..5d680f9b9a469e9d2b250daebc2f73442789fc10 100644 (file)
@@ -10,7 +10,6 @@ static void _test_one(int line, const char *input, const char *output) {
         CalendarSpec *c;
         _cleanup_free_ char *p = NULL, *q = NULL;
         usec_t u;
-        char buf[FORMAT_TIMESTAMP_MAX];
         int r;
 
         assert_se(calendar_spec_from_string(input, &c) >= 0);
@@ -22,7 +21,7 @@ static void _test_one(int line, const char *input, const char *output) {
 
         u = now(CLOCK_REALTIME);
         r = calendar_spec_next_usec(c, u, &u);
-        log_info("Next: %s", r < 0 ? strerror_safe(r) : format_timestamp(buf, sizeof buf, u));
+        log_info("Next: %s", r < 0 ? strerror_safe(r) : FORMAT_TIMESTAMP(u));
         calendar_spec_free(c);
 
         assert_se(calendar_spec_from_string(p, &c) >= 0);
@@ -37,7 +36,6 @@ static void _test_next(int line, const char *input, const char *new_tz, usec_t a
         CalendarSpec *c;
         usec_t u;
         char *old_tz;
-        char buf[FORMAT_TIMESTAMP_MAX];
         int r;
 
         old_tz = getenv("TZ");
@@ -56,7 +54,7 @@ static void _test_next(int line, const char *input, const char *new_tz, usec_t a
 
         u = after;
         r = calendar_spec_next_usec(c, after, &u);
-        log_info("At: %s", r < 0 ? strerror_safe(r) : format_timestamp_style(buf, sizeof buf, u, TIMESTAMP_US));
+        log_info("At: %s", r < 0 ? strerror_safe(r) : FORMAT_TIMESTAMP_STYLE(u, TIMESTAMP_US));
         if (expect != USEC_INFINITY)
                 assert_se(r >= 0 && u == expect);
         else
@@ -93,18 +91,17 @@ static void test_timestamp(void) {
 static void test_hourly_bug_4031(void) {
         CalendarSpec *c;
         usec_t n, u, w;
-        char buf[FORMAT_TIMESTAMP_MAX], zaf[FORMAT_TIMESTAMP_MAX];
         int r;
 
         assert_se(calendar_spec_from_string("hourly", &c) >= 0);
         n = now(CLOCK_REALTIME);
         assert_se((r = calendar_spec_next_usec(c, n, &u)) >= 0);
 
-        log_info("Now: %s (%"PRIu64")", format_timestamp_style(buf, sizeof buf, n, TIMESTAMP_US), n);
-        log_info("Next hourly: %s (%"PRIu64")", r < 0 ? strerror_safe(r) : format_timestamp_style(buf, sizeof buf, u, TIMESTAMP_US), u);
+        log_info("Now: %s (%"PRIu64")", FORMAT_TIMESTAMP_STYLE(n, TIMESTAMP_US), n);
+        log_info("Next hourly: %s (%"PRIu64")", r < 0 ? strerror_safe(r) : FORMAT_TIMESTAMP_STYLE(u, TIMESTAMP_US), u);
 
         assert_se((r = calendar_spec_next_usec(c, u, &w)) >= 0);
-        log_info("Next hourly: %s (%"PRIu64")", r < 0 ? strerror_safe(r) : format_timestamp_style(zaf, sizeof zaf, w, TIMESTAMP_US), w);
+        log_info("Next hourly: %s (%"PRIu64")", r < 0 ? strerror_safe(r) : FORMAT_TIMESTAMP_STYLE(w, TIMESTAMP_US), w);
 
         assert_se(n < u);
         assert_se(u <= n + USEC_PER_HOUR);
index 892f8a073ff5328d25d81fa223f78457afbc016e..635c44675b2217721e03c490585057c62006f0fb 100644 (file)
@@ -72,7 +72,7 @@ static int parse_argv(int argc, char *argv[]) {
                         return -EINVAL;
 
                 default:
-                        assert_not_reached("Unhandled option");
+                        assert_not_reached();
                 }
 
         if (optind == argc)
index 47b70967385554e6b73de64be07325dbe4e6d8f8..355f4e17de5d99cff148fa5c8ab27606453825b1 100644 (file)
@@ -15,12 +15,9 @@ static void test_should_pass(const char *p) {
         log_info("\"%s\" → \"%s\"", p, buf);
 
         assert_se(parse_timestamp(buf, &q) >= 0);
-        if (q != t) {
-                char tmp[FORMAT_TIMESTAMP_MAX];
-
+        if (q != t)
                 log_error("round-trip failed: \"%s\" → \"%s\"",
-                          buf, format_timestamp_style(tmp, sizeof(tmp), q, TIMESTAMP_US));
-        }
+                          buf, FORMAT_TIMESTAMP_STYLE(q, TIMESTAMP_US));
         assert_se(q == t);
 
         assert_se(format_timestamp_relative(buf_relative, sizeof(buf_relative), t));
index 991b135a332e00a35125cb3ccf90ebfdc3cc5e10..413e8cd860e734972a56923710789f369e895cfd 100644 (file)
@@ -8,6 +8,8 @@
 static void test_cescape(void) {
         _cleanup_free_ char *t;
 
+        log_info("/* %s */", __func__);
+
         assert_se(t = cescape("abc\\\"\b\f\n\r\t\v\a\003\177\234\313"));
         assert_se(streq(t, "abc\\\\\\\"\\b\\f\\n\\r\\t\\v\\a\\003\\177\\234\\313"));
 }
@@ -15,6 +17,8 @@ static void test_cescape(void) {
 static void test_xescape(void) {
         _cleanup_free_ char *t;
 
+        log_info("/* %s */", __func__);
+
         assert_se(t = xescape("abc\\\"\b\f\n\r\t\v\a\003\177\234\313", ""));
         assert_se(streq(t, "abc\\x5c\"\\x08\\x0c\\x0a\\x0d\\x09\\x0b\\x07\\x03\\x7f\\x9c\\xcb"));
 }
@@ -26,6 +30,8 @@ static void test_xescape_full(bool eight_bits) {
         const unsigned full_fit = !eight_bits ? 55 : 46;
         XEscapeFlags flags = eight_bits * XESCAPE_8_BIT;
 
+        log_info("/* %s */", __func__);
+
         for (unsigned i = 0; i < 60; i++) {
                 _cleanup_free_ char *t, *q;
 
@@ -60,6 +66,8 @@ static void test_xescape_full(bool eight_bits) {
 static void test_cunescape(void) {
         _cleanup_free_ char *unescaped;
 
+        log_info("/* %s */", __func__);
+
         assert_se(cunescape("abc\\\\\\\"\\b\\f\\a\\n\\r\\t\\v\\003\\177\\234\\313\\000\\x00", 0, &unescaped) < 0);
         assert_se(cunescape("abc\\\\\\\"\\b\\f\\a\\n\\r\\t\\v\\003\\177\\234\\313\\000\\x00", UNESCAPE_RELAX, &unescaped) >= 0);
         assert_se(streq_ptr(unescaped, "abc\\\"\b\f\a\n\r\t\v\003\177\234\313\\000\\x00"));
@@ -133,6 +141,8 @@ static void test_shell_escape_one(const char *s, const char *bad, const char *ex
 }
 
 static void test_shell_escape(void) {
+        log_info("/* %s */", __func__);
+
         test_shell_escape_one("", "", "");
         test_shell_escape_one("\\", "", "\\\\");
         test_shell_escape_one("foobar", "", "foobar");
@@ -150,6 +160,7 @@ static void test_shell_maybe_quote_one(const char *s, ShellEscapeFlags flags, co
 }
 
 static void test_shell_maybe_quote(void) {
+        log_info("/* %s */", __func__);
 
         test_shell_maybe_quote_one("", 0, "");
         test_shell_maybe_quote_one("", SHELL_ESCAPE_EMPTY, "\"\"");
@@ -192,6 +203,29 @@ static void test_shell_maybe_quote(void) {
         test_shell_maybe_quote_one("głąb\002\003rząd", SHELL_ESCAPE_POSIX, "$'głąb\\002\\003rząd'");
 }
 
+static void test_quote_command_line_one(char **argv, const char *expected) {
+        _cleanup_free_ char *s;
+
+        assert_se(s = quote_command_line(argv));
+        log_info("%s", s);
+        assert_se(streq(s, expected));
+}
+
+static void test_quote_command_line(void) {
+        log_info("/* %s */", __func__);
+
+        test_quote_command_line_one(STRV_MAKE("true", "true"),
+                                    "true true");
+        test_quote_command_line_one(STRV_MAKE("true", "with a space"),
+                                    "true \"with a space\"");
+        test_quote_command_line_one(STRV_MAKE("true", "with a 'quote'"),
+                                    "true \"with a 'quote'\"");
+        test_quote_command_line_one(STRV_MAKE("true", "with a \"quote\""),
+                                    "true \"with a \\\"quote\\\"\"");
+        test_quote_command_line_one(STRV_MAKE("true", "$dollar"),
+                                    "true \"\\$dollar\"");
+}
+
 int main(int argc, char *argv[]) {
         test_setup_logging(LOG_DEBUG);
 
@@ -202,6 +236,7 @@ int main(int argc, char *argv[]) {
         test_cunescape();
         test_shell_escape();
         test_shell_maybe_quote();
+        test_quote_command_line();
 
         return 0;
 }
diff --git a/src/test/test-ether-addr-util.c b/src/test/test-ether-addr-util.c
new file mode 100644 (file)
index 0000000..8942158
--- /dev/null
@@ -0,0 +1,42 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+
+#include "ether-addr-util.h"
+#include "tests.h"
+
+#define INFINIBAD_ADDR_1 ((const struct hw_addr_data){ .length = 20, .infiniband = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20} })
+
+static void test_HW_ADDR_TO_STRING(void) {
+        log_info("/* %s */", __func__);
+
+        const char *s = HW_ADDR_TO_STR(&(const struct hw_addr_data){6});
+        log_info("null: %s", s);
+
+        log_info("null×2: %s, %s",
+                 HW_ADDR_TO_STR(&(const struct hw_addr_data){6}),
+                 HW_ADDR_TO_STR(&(const struct hw_addr_data){6}));
+        log_info("null×3: %s, %s, %s",
+                 HW_ADDR_TO_STR(&(const struct hw_addr_data){6}),
+                 s,
+                 HW_ADDR_TO_STR(&(const struct hw_addr_data){6}));
+
+        log_info("infiniband: %s", HW_ADDR_TO_STR(&INFINIBAD_ADDR_1));
+
+        /* Let's nest function calls in a stupid way. */
+        _cleanup_free_ char *t = NULL;
+        log_info("infiniband×3: %s\n%14s%s\n%14s%s",
+                 HW_ADDR_TO_STR(&(const struct hw_addr_data){20}), "",
+                 t = strdup(HW_ADDR_TO_STR(&INFINIBAD_ADDR_1)), "",
+                 HW_ADDR_TO_STR(&(const struct hw_addr_data){20}));
+
+        const char *p;
+        /* Let's use a separate selection statement */
+        if ((p = HW_ADDR_TO_STR(&(const struct hw_addr_data){6})))
+                log_info("joint: %s, %s", s, p);
+}
+
+int main(int argc, char *argv[]) {
+        test_setup_logging(LOG_INFO);
+
+        test_HW_ADDR_TO_STRING();
+        return 0;
+}
index 5562ac8761ca5bb0bbec2bbcfdc24624074558b6..4e6c90adfae0ae5a783dc2d367b04b94a9363fd2 100644 (file)
@@ -4,6 +4,15 @@
 #include "macro.h"
 #include "string-util.h"
 
+/* Do some basic checks on STRLEN() and DECIMAL_STR_MAX() */
+assert_cc(STRLEN("xxx") == 3);
+assert_cc(STRLEN("") == 0);
+assert_cc(DECIMAL_STR_MAX(uint8_t) == 5);
+assert_cc(DECIMAL_STR_MAX(int8_t) == 5);
+assert_cc(DECIMAL_STR_MAX(uint64_t) == 22);
+assert_cc(DECIMAL_STR_MAX(char) == 5);
+assert_cc(CONST_MAX(DECIMAL_STR_MAX(int8_t), STRLEN("xxx")) == 5);
+
 static void test_format_bytes_one(uint64_t val, bool trailing_B, const char *iec_with_p, const char *iec_without_p,
                                   const char *si_with_p, const char *si_without_p) {
         char buf[FORMAT_BYTES_MAX];
index b9f20fbd94081f7c419083087cd616f76787d60d..f7bc8a7b2b3e6b6e75db74ab1b542acbc656f0b1 100644 (file)
@@ -752,7 +752,6 @@ static void test_hashmap_many(void) {
 
         for (j = 0; j < ELEMENTSOF(tests); j++) {
                 usec_t ts = now(CLOCK_MONOTONIC), n;
-                char b[FORMAT_TIMESPAN_MAX];
 
                 assert_se(h = hashmap_new(tests[j].ops));
 
@@ -779,7 +778,7 @@ static void test_hashmap_many(void) {
                 hashmap_free(h);
 
                 n = now(CLOCK_MONOTONIC);
-                log_info("test took %s", format_timespan(b, sizeof b, n - ts, 0));
+                log_info("test took %s", FORMAT_TIMESPAN(n - ts, 0));
         }
 }
 
@@ -790,7 +789,6 @@ static void test_hashmap_free(void) {
         Hashmap *h;
         bool slow = slow_tests_enabled();
         usec_t ts, n;
-        char b[FORMAT_TIMESPAN_MAX];
         unsigned n_entries = slow ? 1 << 20 : 240;
 
         const struct {
@@ -824,7 +822,7 @@ static void test_hashmap_free(void) {
                 hashmap_free(h);
 
                 n = now(CLOCK_MONOTONIC);
-                log_info("%s test took %s", tests[j].title, format_timespan(b, sizeof b, n - ts, 0));
+                log_info("%s test took %s", tests[j].title, FORMAT_TIMESPAN(n - ts, 0));
 
                 assert_se(custom_counter == tests[j].expect_counter);
         }
diff --git a/src/test/test-import-util.c b/src/test/test-import-util.c
new file mode 100644 (file)
index 0000000..92ff0f5
--- /dev/null
@@ -0,0 +1,72 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+
+#include "alloc-util.h"
+#include "import-util.h"
+#include "log.h"
+#include "string-util.h"
+#include "tests.h"
+
+static void test_import_url_last_component_one(const char *input, const char *output, int ret) {
+        _cleanup_free_ char *s = NULL;
+
+        assert_se(import_url_last_component(input, &s) == ret);
+        assert_se(streq_ptr(output, s));
+}
+
+static void test_import_url_last_component(void) {
+        test_import_url_last_component_one("https://foobar/waldo/quux", "quux", 0);
+        test_import_url_last_component_one("https://foobar/waldo/quux/", "quux", 0);
+        test_import_url_last_component_one("https://foobar/waldo/", "waldo", 0);
+        test_import_url_last_component_one("https://foobar/", NULL, -EADDRNOTAVAIL);
+        test_import_url_last_component_one("https://foobar", NULL, -EADDRNOTAVAIL);
+        test_import_url_last_component_one("https://foobar/waldo/quux?foo=bar", "quux", 0);
+        test_import_url_last_component_one("https://foobar/waldo/quux/?foo=bar", "quux", 0);
+        test_import_url_last_component_one("https://foobar/waldo/quux/?foo=bar#piep", "quux", 0);
+        test_import_url_last_component_one("https://foobar/waldo/quux/#piep", "quux", 0);
+        test_import_url_last_component_one("https://foobar/waldo/quux#piep", "quux", 0);
+        test_import_url_last_component_one("https://", NULL, -EINVAL);
+        test_import_url_last_component_one("", NULL, -EINVAL);
+        test_import_url_last_component_one(":", NULL, -EINVAL);
+        test_import_url_last_component_one(":/", NULL, -EINVAL);
+        test_import_url_last_component_one("x:/", NULL, -EINVAL);
+        test_import_url_last_component_one("x:y", NULL, -EADDRNOTAVAIL);
+        test_import_url_last_component_one("x:y/z", "z", 0);
+}
+
+static void test_import_url_change_suffix_one(const char *input, size_t n, const char *suffix, const char *output, int ret) {
+        _cleanup_free_ char *s = NULL;
+
+        assert_se(import_url_change_suffix(input, n, suffix, &s) == ret);
+        assert_se(streq_ptr(output, s));
+}
+
+static void test_import_url_change_suffix(void) {
+        test_import_url_change_suffix_one("https://foobar/waldo/quux", 1, "wuff", "https://foobar/waldo/wuff", 0);
+        test_import_url_change_suffix_one("https://foobar/waldo/quux/", 1, "wuff", "https://foobar/waldo/wuff", 0);
+        test_import_url_change_suffix_one("https://foobar/waldo/quux///?mief", 1, "wuff", "https://foobar/waldo/wuff", 0);
+        test_import_url_change_suffix_one("https://foobar/waldo/quux///?mief#opopo", 1, "wuff", "https://foobar/waldo/wuff", 0);
+        test_import_url_change_suffix_one("https://foobar/waldo/quux/quff", 2, "wuff", "https://foobar/waldo/wuff", 0);
+        test_import_url_change_suffix_one("https://foobar/waldo/quux/quff/", 2, "wuff", "https://foobar/waldo/wuff", 0);
+        test_import_url_change_suffix_one("https://foobar/waldo/quux/quff", 0, "wuff", "https://foobar/waldo/quux/quff/wuff", 0);
+        test_import_url_change_suffix_one("https://foobar/waldo/quux/quff?aa?bb##4", 0, "wuff", "https://foobar/waldo/quux/quff/wuff", 0);
+        test_import_url_change_suffix_one("https://", 0, "wuff", NULL, -EINVAL);
+        test_import_url_change_suffix_one("", 0, "wuff", NULL, -EINVAL);
+        test_import_url_change_suffix_one(":", 0, "wuff", NULL, -EINVAL);
+        test_import_url_change_suffix_one(":/", 0, "wuff", NULL, -EINVAL);
+        test_import_url_change_suffix_one("x:/", 0, "wuff", NULL, -EINVAL);
+        test_import_url_change_suffix_one("x:y", 0, "wuff", "x:y/wuff", 0);
+        test_import_url_change_suffix_one("x:y/z", 0, "wuff", "x:y/z/wuff", 0);
+        test_import_url_change_suffix_one("x:y/z/", 0, "wuff", "x:y/z/wuff", 0);
+        test_import_url_change_suffix_one("x:y/z/", 1, "wuff", "x:y/wuff", 0);
+        test_import_url_change_suffix_one("x:y/z/", 2, "wuff", "x:y/wuff", 0);
+}
+
+int main(int argc, char *argv[]) {
+
+        test_setup_logging(LOG_INFO);
+
+        test_import_url_last_component();
+        test_import_url_change_suffix();
+
+        return 0;
+}
index 50ed23a4ee3eaa9ab4a8b71e8c6d87ad47e65b92..30494f7fa1fe443396a7a8fab234e2a9d226992b 100644 (file)
@@ -284,7 +284,7 @@ static void test_linked_units(const char *root) {
                 else if (q && streq(changes[i].path, q))
                         q = NULL;
                 else
-                        assert_not_reached("wut?");
+                        assert_not_reached();
         }
         assert(!p && !q);
         unit_file_changes_free(changes, n_changes);
@@ -305,7 +305,7 @@ static void test_linked_units(const char *root) {
                 else if (q && streq(changes[i].path, q))
                         q = NULL;
                 else
-                        assert_not_reached("wut?");
+                        assert_not_reached();
         }
         assert(!p && !q);
         unit_file_changes_free(changes, n_changes);
@@ -326,7 +326,7 @@ static void test_linked_units(const char *root) {
                 else if (q && streq(changes[i].path, q))
                         q = NULL;
                 else
-                        assert_not_reached("wut?");
+                        assert_not_reached();
         }
         assert(!p && !q);
         unit_file_changes_free(changes, n_changes);
index 972423e2fa2856ffd825f22c702156c2f9f36398..e22481b1b6e5147a0115a94f8780235892546f65 100644 (file)
@@ -89,7 +89,7 @@ static void test_keymaps(void) {
 
 #define dump_glyph(x) log_info(STRINGIFY(x) ": %s", special_glyph(x))
 static void dump_special_glyphs(void) {
-        assert_cc(SPECIAL_GLYPH_TOUCH + 1 == _SPECIAL_GLYPH_MAX);
+        assert_cc(SPECIAL_GLYPH_SPARKLES + 1 == _SPECIAL_GLYPH_MAX);
 
         log_info("/* %s */", __func__);
 
@@ -120,6 +120,9 @@ static void dump_special_glyphs(void) {
         dump_glyph(SPECIAL_GLYPH_DEPRESSED_SMILEY);
         dump_glyph(SPECIAL_GLYPH_LOCK_AND_KEY);
         dump_glyph(SPECIAL_GLYPH_TOUCH);
+        dump_glyph(SPECIAL_GLYPH_RECYCLING);
+        dump_glyph(SPECIAL_GLYPH_DOWNLOAD);
+        dump_glyph(SPECIAL_GLYPH_SPARKLES);
 }
 
 int main(int argc, char *argv[]) {
index 4c041cd57f9d31cfd83219c3c23ffdb637974f66..ceea7a62f5155b8cc3c4b3735f7bdce9bf9a584a 100644 (file)
@@ -348,7 +348,7 @@ static void test_prefixes(void) {
         assert_se(values[i] == NULL);
 
         PATH_FOREACH_PREFIX(s, "////")
-                assert_not_reached("Wut?");
+                assert_not_reached();
 
         b = false;
         PATH_FOREACH_PREFIX_MORE(s, "////") {
@@ -359,7 +359,7 @@ static void test_prefixes(void) {
         assert_se(b);
 
         PATH_FOREACH_PREFIX(s, "")
-                assert_not_reached("wut?");
+                assert_not_reached();
 
         b = false;
         PATH_FOREACH_PREFIX_MORE(s, "") {
index 1f5ee7d768d994f4c55a519d3cdc4e094f052eb0..a72523bd028f4b107757519e3b436c4bb3cb730e 100644 (file)
@@ -82,7 +82,7 @@ static int parse_item_given(const char *key, const char *value, void *data) {
         else if (in_initrd() && !*strip && proc_cmdline_key_streq(key, "rd.zumm"))
                 assert_se(!value);
         else
-                assert_not_reached("Bad key!");
+                assert_not_reached();
 
         return 0;
 }
index b2679e30fb24b17794b81fab7546895323998202..a961436b40a6a2b29983e001064f2f77f19f721d 100644 (file)
@@ -9,7 +9,6 @@
 #include "tests.h"
 
 int main(int argc, char *argv[]) {
-        char buf[CONST_MAX(FORMAT_TIMESPAN_MAX, FORMAT_BYTES_MAX)];
         nsec_t nsec;
         uint64_t v;
         int r;
@@ -18,10 +17,10 @@ int main(int argc, char *argv[]) {
         log_open();
 
         assert_se(procfs_cpu_get_usage(&nsec) >= 0);
-        log_info("Current system CPU time: %s", format_timespan(buf, sizeof(buf), nsec/NSEC_PER_USEC, 1));
+        log_info("Current system CPU time: %s", FORMAT_TIMESPAN(nsec/NSEC_PER_USEC, 1));
 
         assert_se(procfs_memory_get_used(&v) >= 0);
-        log_info("Current memory usage: %s", format_bytes(buf, sizeof(buf), v));
+        log_info("Current memory usage: %s", FORMAT_BYTES(v));
 
         assert_se(procfs_tasks_get_current(&v) >= 0);
         log_info("Current number of tasks: %" PRIu64, v);
index 134525288f1a4b971e2bf49cb5d63a8a4d118564..88ff35fc5a198e58d50111d8992471deb5fe5e15 100644 (file)
@@ -640,10 +640,10 @@ static void test_strv_foreach_backwards(void) {
                 assert_se(streq_ptr(*check, input_table_multiple[i--]));
 
         STRV_FOREACH_BACKWARDS(check, (char**) NULL)
-                assert_not_reached("Let's see that we check empty strv right, too.");
+                assert_not_reached();
 
         STRV_FOREACH_BACKWARDS(check, (char**) { NULL })
-                assert_not_reached("Let's see that we check empty strv right, too.");
+                assert_not_reached();
 }
 
 static void test_strv_foreach_pair(void) {
index 6f4675aaf47b7e8520a18efa0fba0c29a3fc1517..7079bffa7fe4aa33a5606977040153290a852924 100644 (file)
@@ -335,8 +335,7 @@ static void test_format_timestamp(void) {
                 char buf[MAX(FORMAT_TIMESTAMP_MAX, FORMAT_TIMESPAN_MAX)];
                 usec_t x, y;
 
-                random_bytes(&x, sizeof(x));
-                x = x % (2147483600 * USEC_PER_SEC) + 1;
+                x = random_u64_range(2147483600 * USEC_PER_SEC) + 1;
 
                 assert_se(format_timestamp(buf, sizeof(buf), x));
                 log_debug("%s", buf);
@@ -370,6 +369,25 @@ static void test_format_timestamp(void) {
         }
 }
 
+static void test_FORMAT_TIMESTAMP(void) {
+        log_info("/* %s */", __func__);
+
+        for (unsigned i = 0; i < 100; i++) {
+                _cleanup_free_ char *buf;
+                usec_t x, y;
+
+                x = random_u64_range(2147483600 * USEC_PER_SEC) + 1;
+
+                /* strbuf() is to test the macro in an argument to a function call. */
+                assert_se(buf = strdup(FORMAT_TIMESTAMP(x)));
+                log_debug("%s", buf);
+                assert_se(parse_timestamp(buf, &y) >= 0);
+                assert_se(x / USEC_PER_SEC == y / USEC_PER_SEC);
+
+                assert_se(streq(FORMAT_TIMESTAMP(x), buf));
+        }
+}
+
 static void test_format_timestamp_relative(void) {
         log_info("/* %s */", __func__);
 
@@ -624,6 +642,7 @@ int main(int argc, char *argv[]) {
         test_usec_sub_signed();
         test_usec_sub_unsigned();
         test_format_timestamp();
+        test_FORMAT_TIMESTAMP();
         test_format_timestamp_relative();
         test_format_timestamp_utc();
         test_deserialize_dual_timestamp();
index 3eef2c30198dfd1bb1a1b7bb4d2713ebc9c2a06f..4d9008ba3394e07abe39c736323ed9f2779a3d46 100644 (file)
@@ -321,7 +321,6 @@ static void test_raw_clone(void) {
 
 static void test_physical_memory(void) {
         uint64_t p;
-        char buf[FORMAT_BYTES_MAX];
 
         log_info("/* %s */", __func__);
 
@@ -330,7 +329,7 @@ static void test_physical_memory(void) {
         assert_se(p < UINT64_MAX);
         assert_se(p % page_size() == 0);
 
-        log_info("Memory: %s (%" PRIu64 ")", format_bytes(buf, sizeof(buf), p), p);
+        log_info("Memory: %s (%" PRIu64 ")", FORMAT_BYTES(p), p);
 }
 
 static void test_physical_memory_scale(void) {
@@ -432,7 +431,7 @@ static void test_foreach_pointer(void) {
                         break;
 
                 default:
-                        assert_not_reached("unexpected index");
+                        assert_not_reached();
                         break;
                 }
 
@@ -481,7 +480,7 @@ static void test_foreach_pointer(void) {
                         break;
 
                 default:
-                        assert_not_reached("unexpected index");
+                        assert_not_reached();
                         break;
                 }
 
index 6aa55ba17efe40e3bcd1530067df2cea9e426f95..7017b02ac9b8d481c2e48529cac557520a24f96a 100644 (file)
@@ -51,9 +51,7 @@ cleanup:
 }
 
 static void test_getcrtime(void) {
-
         _cleanup_close_ int fd = -1;
-        char ts[FORMAT_TIMESTAMP_MAX];
         const char *vt;
         usec_t usec, k;
         int r;
@@ -67,7 +65,7 @@ static void test_getcrtime(void) {
         if (r < 0)
                 log_debug_errno(r, "btime: %m");
         else
-                log_debug("btime: %s", format_timestamp(ts, sizeof(ts), usec));
+                log_debug("btime: %s", FORMAT_TIMESTAMP(usec));
 
         k = now(CLOCK_REALTIME);
 
index d31f67f4cb3e4877c77a60220753b0567088476c..6a4bbdbb480c60aab2bf499e65a8449540c6264d 100644 (file)
@@ -359,8 +359,6 @@ DEFINE_PRIVATE_STRING_TABLE_LOOKUP_TO_STRING(ntp_leap, uint32_t);
 REENABLE_WARNING;
 
 static int print_ntp_status_info(NTPStatusInfo *i) {
-        char ts[FORMAT_TIMESPAN_MAX], jitter[FORMAT_TIMESPAN_MAX],
-                tmin[FORMAT_TIMESPAN_MAX], tmax[FORMAT_TIMESPAN_MAX];
         usec_t delay, t14, t23, offset, root_distance;
         _cleanup_(table_unrefp) Table *table = NULL;
         bool offset_sign;
@@ -407,9 +405,9 @@ static int print_ntp_status_info(NTPStatusInfo *i) {
                 return table_log_add_error(r);
 
         r = table_add_cell_stringf(table, NULL, "%s (min: %s; max %s)",
-                                   format_timespan(ts, sizeof(ts), i->poll_interval, 0),
-                                   format_timespan(tmin, sizeof(tmin), i->poll_min, 0),
-                                   format_timespan(tmax, sizeof(tmax), i->poll_max, 0));
+                                   FORMAT_TIMESPAN(i->poll_interval, 0),
+                                   FORMAT_TIMESPAN(i->poll_min, 0),
+                                   FORMAT_TIMESPAN(i->poll_max, 0));
         if (r < 0)
                 return table_log_add_error(r);
 
@@ -468,7 +466,7 @@ static int print_ntp_status_info(NTPStatusInfo *i) {
                 return table_log_add_error(r);
 
         r = table_add_cell_stringf(table, NULL, "%s (%" PRIi32 ")",
-                                   format_timespan(ts, sizeof(ts), DIV_ROUND_UP((nsec_t) (exp2(i->precision) * NSEC_PER_SEC), NSEC_PER_USEC), 0),
+                                   FORMAT_TIMESPAN(DIV_ROUND_UP((nsec_t) (exp2(i->precision) * NSEC_PER_SEC), NSEC_PER_USEC), 0),
                                    i->precision);
         if (r < 0)
                 return table_log_add_error(r);
@@ -478,8 +476,8 @@ static int print_ntp_status_info(NTPStatusInfo *i) {
                 return table_log_add_error(r);
 
         r = table_add_cell_stringf(table, NULL, "%s (max: %s)",
-                                   format_timespan(ts, sizeof(ts), root_distance, 0),
-                                   format_timespan(tmax, sizeof(tmax), i->root_distance_max, 0));
+                                   FORMAT_TIMESPAN(root_distance, 0),
+                                   FORMAT_TIMESPAN(i->root_distance_max, 0));
         if (r < 0)
                 return table_log_add_error(r);
 
@@ -489,15 +487,15 @@ static int print_ntp_status_info(NTPStatusInfo *i) {
 
         r = table_add_cell_stringf(table, NULL, "%s%s",
                                    offset_sign ? "+" : "-",
-                                   format_timespan(ts, sizeof(ts), offset, 0));
+                                   FORMAT_TIMESPAN(offset, 0));
         if (r < 0)
                 return table_log_add_error(r);
 
         r = table_add_many(table,
                            TABLE_STRING, "Delay:",
-                           TABLE_STRING, format_timespan(ts, sizeof(ts), delay, 0),
+                           TABLE_STRING, FORMAT_TIMESPAN(delay, 0),
                            TABLE_STRING, "Jitter:",
-                           TABLE_STRING, format_timespan(jitter, sizeof(jitter), i->jitter, 0),
+                           TABLE_STRING, FORMAT_TIMESPAN(i->jitter, 0),
                            TABLE_STRING, "Packet count:",
                            TABLE_UINT64, i->packet_count);
         if (r < 0)
@@ -717,7 +715,6 @@ static int print_timesync_property(const char *name, const char *expected_value,
         case SD_BUS_TYPE_STRUCT:
                 if (streq(name, "NTPMessage")) {
                         _cleanup_(ntp_status_info_clear) NTPStatusInfo i = {};
-                        char ts[FORMAT_TIMESPAN_MAX], stamp[FORMAT_TIMESTAMP_MAX];
 
                         r = map_ntp_message(NULL, NULL, m, NULL, &i);
                         if (r < 0)
@@ -733,28 +730,21 @@ static int print_timesync_property(const char *name, const char *expected_value,
 
                         printf("{ Leap=%u, Version=%u, Mode=%u, Stratum=%u, Precision=%i,",
                                i.leap, i.version, i.mode, i.stratum, i.precision);
-                        printf(" RootDelay=%s,",
-                               format_timespan(ts, sizeof(ts), i.root_delay, 0));
-                        printf(" RootDispersion=%s,",
-                               format_timespan(ts, sizeof(ts), i.root_dispersion, 0));
+                        printf(" RootDelay=%s,", FORMAT_TIMESPAN(i.root_delay, 0));
+                        printf(" RootDispersion=%s,", FORMAT_TIMESPAN(i.root_dispersion, 0));
 
                         if (i.stratum == 1)
                                 printf(" Reference=%s,", i.reference.str);
                         else
                                 printf(" Reference=%" PRIX32 ",", be32toh(i.reference.val));
 
-                        printf(" OriginateTimestamp=%s,",
-                               format_timestamp(stamp, sizeof(stamp), i.origin));
-                        printf(" ReceiveTimestamp=%s,",
-                               format_timestamp(stamp, sizeof(stamp), i.recv));
-                        printf(" TransmitTimestamp=%s,",
-                               format_timestamp(stamp, sizeof(stamp), i.trans));
-                        printf(" DestinationTimestamp=%s,",
-                               format_timestamp(stamp, sizeof(stamp), i.dest));
+                        printf(" OriginateTimestamp=%s,", FORMAT_TIMESTAMP(i.origin));
+                        printf(" ReceiveTimestamp=%s,", FORMAT_TIMESTAMP(i.recv));
+                        printf(" TransmitTimestamp=%s,", FORMAT_TIMESTAMP(i.trans));
+                        printf(" DestinationTimestamp=%s,", FORMAT_TIMESTAMP(i.dest));
                         printf(" Ignored=%s PacketCount=%" PRIu64 ",",
                                yes_no(i.spike), i.packet_count);
-                        printf(" Jitter=%s }\n",
-                               format_timespan(ts, sizeof(ts), i.jitter, 0));
+                        printf(" Jitter=%s }\n", FORMAT_TIMESPAN(i.jitter, 0));
 
                         return 1;
 
@@ -1009,7 +999,7 @@ static int parse_argv(int argc, char *argv[]) {
                         return -EINVAL;
 
                 default:
-                        assert_not_reached("Unhandled option");
+                        assert_not_reached();
                 }
 
         return 1;
index f7ec317f413df91ed293038d0f532454fcbcb141..79dfd47266965193d04795bca9f52634b1ac5f00 100644 (file)
@@ -79,7 +79,7 @@ int server_name_new(
                 LIST_FIND_TAIL(names, m->fallback_servers, tail);
                 LIST_INSERT_AFTER(names, m->fallback_servers, tail, n);
         } else
-                assert_not_reached("Unknown server type");
+                assert_not_reached();
 
         n->manager = m;
 
@@ -110,7 +110,7 @@ ServerName *server_name_free(ServerName *n) {
                 else if (n->type == SERVER_FALLBACK)
                         LIST_REMOVE(names, n->manager->fallback_servers, n);
                 else
-                        assert_not_reached("Unknown server type");
+                        assert_not_reached();
 
                 if (n->manager->current_server_name == n)
                         manager_set_server_name(n->manager, NULL);
index 2a9b113ff484128840d6b090666826b3a8926ea3..892746d5ee62be3380009fddecc85a0861220c01 100644 (file)
@@ -100,9 +100,7 @@ static int clock_state_update(
                 ClockState *sp,
                 sd_event *event) {
 
-        char buf[MAX((size_t)FORMAT_TIMESTAMP_MAX, STRLEN("unrepresentable"))];
         struct timex tx = {};
-        const char * ts;
         usec_t t;
         int r;
 
@@ -149,10 +147,9 @@ static int clock_state_update(
         if (tx.status & STA_NANO)
                 tx.time.tv_usec /= 1000;
         t = timeval_load(&tx.time);
-        ts = format_timestamp_style(buf, sizeof(buf), t, TIMESTAMP_US_UTC);
-        if (!ts)
-                strcpy(buf, "unrepresentable");
-        log_info("adjtime state %d status %x time %s", sp->adjtime_state, tx.status, ts);
+
+        log_info("adjtime state %d status %x time %s", sp->adjtime_state, tx.status,
+                 FORMAT_TIMESTAMP_STYLE(t, TIMESTAMP_US_UTC) ?: "unrepresentable");
 
         sp->has_watchfile = access("/run/systemd/timesync/synchronized", F_OK) >= 0;
         if (sp->has_watchfile)
index 1a961d125bbdde3e250224b343d660ca306cf79a..e509c63961ea13ec70fccfd014440ba24b3c9b30 100644 (file)
@@ -60,7 +60,7 @@ static int parse_argv(int argc, char *argv[]) {
                         return -EINVAL;
 
                 default:
-                        assert_not_reached("Unhandled option");
+                        assert_not_reached();
                 }
 
         return 0;
index b32b709ef5b055f2402531a8144ff4cc17dff7cb..dd05dd9b4ee4f9dbe5d651df1208994bcf3af8ce 100644 (file)
@@ -544,22 +544,20 @@ static bool needs_cleanup(
                 bool is_dir) {
 
         if (FLAGS_SET(age_by, AGE_BY_MTIME) && mtime != NSEC_INFINITY && mtime >= cutoff) {
-                char a[FORMAT_TIMESTAMP_MAX];
                 /* Follows spelling in stat(1). */
                 log_debug("%s \"%s\": modify time %s is too new.",
                           is_dir ? "Directory" : "File",
                           sub_path,
-                          format_timestamp_style(a, sizeof(a), mtime / NSEC_PER_USEC, TIMESTAMP_US));
+                          FORMAT_TIMESTAMP_STYLE(mtime / NSEC_PER_USEC, TIMESTAMP_US));
 
                 return false;
         }
 
         if (FLAGS_SET(age_by, AGE_BY_ATIME) && atime != NSEC_INFINITY && atime >= cutoff) {
-                char a[FORMAT_TIMESTAMP_MAX];
                 log_debug("%s \"%s\": access time %s is too new.",
                           is_dir ? "Directory" : "File",
                           sub_path,
-                          format_timestamp_style(a, sizeof(a), atime / NSEC_PER_USEC, TIMESTAMP_US));
+                          FORMAT_TIMESTAMP_STYLE(atime / NSEC_PER_USEC, TIMESTAMP_US));
 
                 return false;
         }
@@ -569,21 +567,19 @@ static bool needs_cleanup(
          * by default for directories, because we change it when deleting.
          */
         if (FLAGS_SET(age_by, AGE_BY_CTIME) && ctime != NSEC_INFINITY && ctime >= cutoff) {
-                char a[FORMAT_TIMESTAMP_MAX];
                 log_debug("%s \"%s\": change time %s is too new.",
                           is_dir ? "Directory" : "File",
                           sub_path,
-                          format_timestamp_style(a, sizeof(a), ctime / NSEC_PER_USEC, TIMESTAMP_US));
+                          FORMAT_TIMESTAMP_STYLE(ctime / NSEC_PER_USEC, TIMESTAMP_US));
 
                 return false;
         }
 
         if (FLAGS_SET(age_by, AGE_BY_BTIME) && btime != NSEC_INFINITY && btime >= cutoff) {
-                char a[FORMAT_TIMESTAMP_MAX];
                 log_debug("%s \"%s\": birth time %s is too new.",
                           is_dir ? "Directory" : "File",
                           sub_path,
-                          format_timestamp_style(a, sizeof(a), btime / NSEC_PER_USEC, TIMESTAMP_US));
+                          FORMAT_TIMESTAMP_STYLE(btime / NSEC_PER_USEC, TIMESTAMP_US));
 
                 return false;
         }
@@ -810,13 +806,12 @@ static int dir_cleanup(
 
 finish:
         if (deleted) {
-                char a[FORMAT_TIMESTAMP_MAX], m[FORMAT_TIMESTAMP_MAX];
                 struct timespec ts[2];
 
                 log_debug("Restoring access and modification time on \"%s\": %s, %s",
                           p,
-                          format_timestamp_style(a, sizeof(a), self_atime_nsec / NSEC_PER_USEC, TIMESTAMP_US),
-                          format_timestamp_style(m, sizeof(m), self_mtime_nsec / NSEC_PER_USEC, TIMESTAMP_US));
+                          FORMAT_TIMESTAMP_STYLE(self_atime_nsec / NSEC_PER_USEC, TIMESTAMP_US),
+                          FORMAT_TIMESTAMP_STYLE(self_mtime_nsec / NSEC_PER_USEC, TIMESTAMP_US));
 
                 timespec_store_nsec(ts + 0, self_atime_nsec);
                 timespec_store_nsec(ts + 1, self_mtime_nsec);
@@ -2452,7 +2447,7 @@ static int remove_item_instance(Item *i, const char *instance) {
                 break;
 
         default:
-                assert_not_reached("wut?");
+                assert_not_reached();
         }
 
         return 0;
@@ -2503,7 +2498,6 @@ static char *age_by_to_string(AgeBy ab, bool is_dir) {
 }
 
 static int clean_item_instance(Item *i, const char* instance) {
-        char timestamp[FORMAT_TIMESTAMP_MAX];
         _cleanup_closedir_ DIR *d = NULL;
         STRUCT_STATX_DEFINE(sx);
         int mountpoint, r;
@@ -2562,7 +2556,7 @@ static int clean_item_instance(Item *i, const char* instance) {
                 log_debug("Cleanup threshold for %s \"%s\" is %s; age-by: %s%s",
                           mountpoint ? "mount point" : "directory",
                           instance,
-                          format_timestamp_style(timestamp, sizeof(timestamp), cutoff, TIMESTAMP_US),
+                          FORMAT_TIMESTAMP_STYLE(cutoff, TIMESTAMP_US),
                           ab_f, ab_d);
         }
 
@@ -2775,8 +2769,6 @@ static bool should_include_path(const char *path) {
 }
 
 static int specifier_expansion_from_arg(Item *i) {
-        _cleanup_free_ char *unescaped = NULL, *resolved = NULL;
-        char **xattr;
         int r;
 
         assert(i);
@@ -2789,33 +2781,37 @@ static int specifier_expansion_from_arg(Item *i) {
         case CREATE_SYMLINK:
         case CREATE_FILE:
         case TRUNCATE_FILE:
-        case WRITE_FILE:
-                r = cunescape(i->argument, 0, &unescaped);
-                if (r < 0)
-                        return log_error_errno(r, "Failed to unescape parameter to write: %s", i->argument);
+        case WRITE_FILE: {
+                _cleanup_free_ char *unescaped = NULL, *resolved = NULL;
+                ssize_t l;
+
+                l = cunescape(i->argument, 0, &unescaped);
+                if (l < 0)
+                        return log_error_errno(l, "Failed to unescape parameter to write: %s", i->argument);
 
                 r = specifier_printf(unescaped, PATH_MAX-1, specifier_table, arg_root, NULL, &resolved);
                 if (r < 0)
                         return r;
 
-                free_and_replace(i->argument, resolved);
-                break;
-
+                return free_and_replace(i->argument, resolved);
+        }
         case SET_XATTR:
-        case RECURSIVE_SET_XATTR:
+        case RECURSIVE_SET_XATTR: {
+                char **xattr;
                 STRV_FOREACH(xattr, i->xattrs) {
+                        _cleanup_free_ char *resolved = NULL;
+
                         r = specifier_printf(*xattr, SIZE_MAX, specifier_table, arg_root, NULL, &resolved);
                         if (r < 0)
                                 return r;
 
                         free_and_replace(*xattr, resolved);
                 }
-                break;
-
+                return 0;
+        }
         default:
-                break;
+                return 0;
         }
-        return 0;
 }
 
 static int patch_var_run(const char *fname, unsigned line, char **path) {
@@ -3509,7 +3505,7 @@ static int parse_argv(int argc, char *argv[]) {
                         return -EINVAL;
 
                 default:
-                        assert_not_reached("Unhandled option");
+                        assert_not_reached();
                 }
 
         if (arg_operation == 0 && !arg_cat_config)
@@ -3857,7 +3853,7 @@ static int run(int argc, char *argv[]) {
                 else if (phase == PHASE_CREATE)
                         op = arg_operation & OPERATION_CREATE;
                 else
-                        assert_not_reached("unexpected phase");
+                        assert_not_reached();
 
                 if (op == 0) /* Nothing requested in this phase */
                         continue;
index 59b144972b82c0a0d757536901c31d7eee7c55ee..7699bad9e048218a09b6be1360e872f8d60c2739 100644 (file)
@@ -508,7 +508,7 @@ static int parse_argv(int argc, char *argv[]) {
                         return -EINVAL;
 
                 default:
-                        assert_not_reached("Unhandled option");
+                        assert_not_reached();
                 }
 
         if (optind != argc)
index df0ee6a3bb2653adc20dfcbd750a861ca7fd5685..a2185350d393af19552cf9b5ffe147a79dd9bc03 100644 (file)
@@ -943,7 +943,7 @@ static int parse_argv(int argc, char *argv[]) {
                 case 'h':
                         return help();
                 default:
-                        assert_not_reached("Unknown option");
+                        assert_not_reached();
                 }
 
         arg_node = argv[optind];
index 64eba0d314e34d203920aa8dff5f81672fe6f20c..4c0ec2eccb97c51974d3bb4d73d1e69c472f4d19 100644 (file)
@@ -665,7 +665,7 @@ static int parse_argv(int argc, char * const *argv) {
                 case '?':
                         return -EINVAL;
                 default:
-                        assert_not_reached("Unknown option");
+                        assert_not_reached();
                 }
 
         return 1;
index 4e80f9bfd715dc78c5d26615f8103e83e497d32e..87bb341a56259cd69471ca4169023335b4ce1e89 100644 (file)
@@ -115,47 +115,45 @@ libudevd_core = static_library(
         link_with : udev_link_with,
         dependencies : [libblkid, libkmod])
 
-udev_id_progs = [['ata_id/ata_id.c'],
-                 ['cdrom_id/cdrom_id.c'],
-                 ['fido_id/fido_id.c',
-                  'fido_id/fido_id_desc.c',
-                  'fido_id/fido_id_desc.h'],
-                 ['scsi_id/scsi_id.c',
-                  'scsi_id/scsi_id.h',
-                  'scsi_id/scsi_serial.c',
-                  'scsi_id/scsi.h'],
-                 ['v4l_id/v4l_id.c'],
-                 ['mtd_probe/mtd_probe.c',
-                  'mtd_probe/mtd_probe.h',
-                  'mtd_probe/probe_smartmedia.c']]
+udev_progs = [['ata_id/ata_id.c'],
+              ['cdrom_id/cdrom_id.c'],
+              ['fido_id/fido_id.c',
+               'fido_id/fido_id_desc.c',
+               'fido_id/fido_id_desc.h'],
+              ['scsi_id/scsi_id.c',
+               'scsi_id/scsi_id.h',
+               'scsi_id/scsi_serial.c',
+               'scsi_id/scsi.h'],
+              ['v4l_id/v4l_id.c'],
+              ['mtd_probe/mtd_probe.c',
+               'mtd_probe/mtd_probe.h',
+               'mtd_probe/probe_smartmedia.c']]
 
 dmi_arches = ['x86', 'x86_64', 'aarch64', 'arm', 'ia64', 'mips']
 if dmi_arches.contains(host_machine.cpu_family())
-        udev_id_progs += [['dmi_memory_id/dmi_memory_id.c']]
+        udev_progs += [['dmi_memory_id/dmi_memory_id.c']]
 endif
 
-foreach prog : udev_id_progs
+udev_prog_paths = {}
+foreach prog : udev_progs
         name = prog[0].split('/')[0]
 
         exe = executable(
                 name,
                 prog,
                 include_directories : includes,
-                dependencies : [versiondep],
+                dependencies : versiondep,
                 link_with : udev_link_with,
                 install_rpath : udev_rpath,
                 install : true,
                 install_dir : udevlibexecdir)
 
-        # TODO: let's use a dictionary instead as soon as we can depend on meson >= 0.47.
-        if name == 'dmi_memory_id'
-                dmi_memory_id_path = exe.full_path()
-        endif
+        udev_prog_paths += {name : exe.full_path()}
 endforeach
 
 if install_sysconfdir_samples
         install_data('udev.conf',
-                     install_dir : join_paths(sysconfdir, 'udev'))
+                     install_dir : sysconfdir / 'udev')
 endif
 
 custom_target(
@@ -169,7 +167,7 @@ custom_target(
 
 if install_sysconfdir
         meson.add_install_script('sh', '-c',
-                                 mkdir_p.format(join_paths(sysconfdir, 'udev/rules.d')))
+                                 mkdir_p.format(sysconfdir / 'udev/rules.d'))
 endif
 
 fuzzers += [
index 8dfe23691bc42110212c62dd2deebae4a6bdd222..fa43548280be603e90b563dabd063bff97d1d552 100644 (file)
@@ -501,7 +501,7 @@ static int link_config_generate_new_name(const LinkConfigContext *ctx, const Lin
                                 (void) sd_device_get_property_value(device, "ID_NET_NAME_MAC", &new_name);
                                 break;
                         default:
-                                assert_not_reached("invalid policy");
+                                assert_not_reached();
                         }
                         if (ifname_valid(new_name)) {
                                 log_device_debug(device, "Policy *%s* yields \"%s\".", name_policy_to_string(policy), new_name);
@@ -569,7 +569,7 @@ static int link_config_apply_alternative_names(sd_netlink **rtnl, const LinkConf
                                 (void) sd_device_get_property_value(device, "ID_NET_NAME_MAC", &n);
                                 break;
                         default:
-                                assert_not_reached("invalid policy");
+                                assert_not_reached();
                         }
                         if (!isempty(n)) {
                                 r = strv_extend(&altnames, n);
index b2d8154d86cbf0e8ed2fecba3d4670b638e602e3..8ce73d03da8e70cb3c1536a6aa981169da337857 100644 (file)
@@ -306,7 +306,7 @@ static int set_options(int argc, char **argv,
                         return -1;
 
                 default:
-                        assert_not_reached("Unknown option");
+                        assert_not_reached();
                 }
 
         if (optind < argc && !dev_specified) {
index fd1752c65fd54dad7780249a9ed08e7197f4bf72..b1a631dea2f17f37b4a589328771ddc5816cc140 100644 (file)
@@ -83,7 +83,7 @@ int main(int argc, char *argv[]) {
                 else if (streq(argv[1], "test2"))
                         test2();
                 else
-                        assert_not_reached("unknown command.");
+                        assert_not_reached();
 
                 return 0;
         }
index d40251331ce85b109ff8b78445d3cee2d277d6fd..5964e30bf1ad6fc5f1a558f9e17bc6ce555c6004 100644 (file)
@@ -28,10 +28,12 @@ static int builtin_net_setup_link(sd_device *dev, int argc, char **argv, bool te
 
         r = link_config_get(ctx, dev, &link);
         if (r < 0) {
-                if (r == -ENOENT)
-                        return log_device_debug_errno(dev, r, "No matching link configuration found.");
                 if (r == -ENODEV)
                         return log_device_debug_errno(dev, r, "Link vanished while searching for configuration for it.");
+                if (r == -ENOENT) {
+                        log_device_debug_errno(dev, r, "No matching link configuration found, ignoring device.");
+                        return 0;
+                }
 
                 return log_device_error_errno(dev, r, "Failed to get link config: %m");
         }
index b28089be71c8935e499ef5d65ff068369bbc3613..2179c8d254b6f8274a6dc7315318528ed975ef1a 100644 (file)
@@ -247,13 +247,13 @@ static ssize_t udev_event_subst_format(
                 r = sd_device_get_devpath(dev, &val);
                 if (r < 0)
                         return r;
-                l = strpcpy(&s, l, val);
+                strpcpy(&s, l, val);
                 break;
         case FORMAT_SUBST_KERNEL:
                 r = sd_device_get_sysname(dev, &val);
                 if (r < 0)
                         return r;
-                l = strpcpy(&s, l, val);
+                strpcpy(&s, l, val);
                 break;
         case FORMAT_SUBST_KERNEL_NUMBER:
                 r = sd_device_get_sysnum(dev, &val);
@@ -261,7 +261,7 @@ static ssize_t udev_event_subst_format(
                         goto null_terminate;
                 if (r < 0)
                         return r;
-                l = strpcpy(&s, l, val);
+                strpcpy(&s, l, val);
                 break;
         case FORMAT_SUBST_ID:
                 if (!event->dev_parent)
@@ -269,7 +269,7 @@ static ssize_t udev_event_subst_format(
                 r = sd_device_get_sysname(event->dev_parent, &val);
                 if (r < 0)
                         return r;
-                l = strpcpy(&s, l, val);
+                strpcpy(&s, l, val);
                 break;
         case FORMAT_SUBST_DRIVER:
                 if (!event->dev_parent)
@@ -279,7 +279,7 @@ static ssize_t udev_event_subst_format(
                         goto null_terminate;
                 if (r < 0)
                         return r;
-                l = strpcpy(&s, l, val);
+                strpcpy(&s, l, val);
                 break;
         case FORMAT_SUBST_MAJOR:
         case FORMAT_SUBST_MINOR: {
@@ -288,7 +288,7 @@ static ssize_t udev_event_subst_format(
                 r = sd_device_get_devnum(dev, &devnum);
                 if (r < 0 && r != -ENOENT)
                         return r;
-                l = strpcpyf(&s, l, "%u", r < 0 ? 0 : type == FORMAT_SUBST_MAJOR ? major(devnum) : minor(devnum));
+                strpcpyf(&s, l, "%u", r < 0 ? 0 : type == FORMAT_SUBST_MAJOR ? major(devnum) : minor(devnum));
                 break;
         }
         case FORMAT_SUBST_RESULT: {
@@ -307,7 +307,7 @@ static ssize_t udev_event_subst_format(
                 }
 
                 if (index == 0)
-                        l = strpcpy(&s, l, event->program_result);
+                        strpcpy(&s, l, event->program_result);
                 else {
                         const char *start, *p;
                         unsigned i;
@@ -329,11 +329,11 @@ static ssize_t udev_event_subst_format(
                         start = p;
                         /* %c{2+} copies the whole string from the second part on */
                         if (has_plus)
-                                l = strpcpy(&s, l, start);
+                                strpcpy(&s, l, start);
                         else {
                                 while (*p && !strchr(WHITESPACE, *p))
                                         p++;
-                                l = strnpcpy(&s, l, start, p - start);
+                                strnpcpy(&s, l, start, p - start);
                         }
                 }
                 break;
@@ -367,7 +367,7 @@ static ssize_t udev_event_subst_format(
                 count = udev_replace_chars(vbuf, UDEV_ALLOWED_CHARS_INPUT);
                 if (count > 0)
                         log_device_debug(dev, "%i character(s) replaced", count);
-                l = strpcpy(&s, l, vbuf);
+                strpcpy(&s, l, vbuf);
                 break;
         }
         case FORMAT_SUBST_PARENT:
@@ -381,7 +381,7 @@ static ssize_t udev_event_subst_format(
                         goto null_terminate;
                 if (r < 0)
                         return r;
-                l = strpcpy(&s, l, val + STRLEN("/dev/"));
+                strpcpy(&s, l, val + STRLEN("/dev/"));
                 break;
         case FORMAT_SUBST_DEVNODE:
                 r = sd_device_get_devname(dev, &val);
@@ -389,34 +389,34 @@ static ssize_t udev_event_subst_format(
                         goto null_terminate;
                 if (r < 0)
                         return r;
-                l = strpcpy(&s, l, val);
+                strpcpy(&s, l, val);
                 break;
         case FORMAT_SUBST_NAME:
                 if (event->name)
-                        l = strpcpy(&s, l, event->name);
+                        strpcpy(&s, l, event->name);
                 else if (sd_device_get_devname(dev, &val) >= 0)
-                        l = strpcpy(&s, l, val + STRLEN("/dev/"));
+                        strpcpy(&s, l, val + STRLEN("/dev/"));
                 else {
                         r = sd_device_get_sysname(dev, &val);
                         if (r < 0)
                                 return r;
-                        l = strpcpy(&s, l, val);
+                        strpcpy(&s, l, val);
                 }
                 break;
         case FORMAT_SUBST_LINKS:
                 FOREACH_DEVICE_DEVLINK(dev, val)
                         if (s == dest)
-                                l = strpcpy(&s, l, val + STRLEN("/dev/"));
+                                strpcpy(&s, l, val + STRLEN("/dev/"));
                         else
-                                l = strpcpyl(&s, l, " ", val + STRLEN("/dev/"), NULL);
+                                strpcpyl(&s, l, " ", val + STRLEN("/dev/"), NULL);
                 if (s == dest)
                         goto null_terminate;
                 break;
         case FORMAT_SUBST_ROOT:
-                l = strpcpy(&s, l, "/dev");
+                strpcpy(&s, l, "/dev");
                 break;
         case FORMAT_SUBST_SYS:
-                l = strpcpy(&s, l, "/sys");
+                strpcpy(&s, l, "/sys");
                 break;
         case FORMAT_SUBST_ENV:
                 if (isempty(attr))
@@ -426,10 +426,10 @@ static ssize_t udev_event_subst_format(
                         goto null_terminate;
                 if (r < 0)
                         return r;
-                l = strpcpy(&s, l, val);
+                strpcpy(&s, l, val);
                 break;
         default:
-                assert_not_reached("Unknown format substitution type");
+                assert_not_reached();
         }
 
         return s - dest;
@@ -600,7 +600,6 @@ reenable:
 
 static int on_spawn_timeout(sd_event_source *s, uint64_t usec, void *userdata) {
         Spawn *spawn = userdata;
-        char timeout[FORMAT_TIMESPAN_MAX];
 
         assert(spawn);
 
@@ -610,20 +609,19 @@ static int on_spawn_timeout(sd_event_source *s, uint64_t usec, void *userdata) {
 
         log_device_error(spawn->device, "Spawned process '%s' ["PID_FMT"] timed out after %s, killing",
                          spawn->cmd, spawn->pid,
-                         format_timespan(timeout, sizeof(timeout), spawn->timeout_usec, USEC_PER_SEC));
+                         FORMAT_TIMESPAN(spawn->timeout_usec, USEC_PER_SEC));
 
         return 1;
 }
 
 static int on_spawn_timeout_warning(sd_event_source *s, uint64_t usec, void *userdata) {
         Spawn *spawn = userdata;
-        char timeout[FORMAT_TIMESPAN_MAX];
 
         assert(spawn);
 
         log_device_warning(spawn->device, "Spawned process '%s' ["PID_FMT"] is taking longer than %s to complete",
                            spawn->cmd, spawn->pid,
-                           format_timespan(timeout, sizeof(timeout), spawn->timeout_warn_usec, USEC_PER_SEC));
+                           FORMAT_TIMESPAN(spawn->timeout_warn_usec, USEC_PER_SEC));
 
         return 1;
 }
@@ -1080,10 +1078,8 @@ void udev_event_execute_run(UdevEvent *event, usec_t timeout_usec, int timeout_s
                                 log_device_debug_errno(event->dev, r, "Failed to run built-in command \"%s\", ignoring: %m", command);
                 } else {
                         if (event->exec_delay_usec > 0) {
-                                char buf[FORMAT_TIMESPAN_MAX];
-
                                 log_device_debug(event->dev, "Delaying execution of \"%s\" for %s.",
-                                                 command, format_timespan(buf, sizeof(buf), event->exec_delay_usec, USEC_PER_SEC));
+                                                 command, FORMAT_TIMESPAN(event->exec_delay_usec, USEC_PER_SEC));
                                 (void) usleep(event->exec_delay_usec);
                         }
 
index bf997fc0eda59f0586fe21d99cb0658c8aed3a64..d050134aef5df0da20075c759ed08638da179738 100644 (file)
@@ -1374,7 +1374,7 @@ static bool token_match_string(UdevRuleToken *token, const char *str) {
                         }
                 break;
         default:
-                assert_not_reached("Invalid match type");
+                assert_not_reached();
         }
 
         return token->op == (match ? OP_MATCH : OP_NOMATCH);
@@ -1405,7 +1405,7 @@ static bool token_match_attr(UdevRuleToken *token, sd_device *dev, UdevEvent *ev
                 value = vbuf;
                 break;
         default:
-                assert_not_reached("Invalid attribute substitution type");
+                assert_not_reached();
         }
 
         /* remove trailing whitespace, if not asked to match for it */
@@ -1607,7 +1607,7 @@ static int udev_rule_apply_token_to_event(
                 else if (streq(k, "virt"))
                         val = virtualization_to_string(detect_virtualization());
                 else
-                        assert_not_reached("Invalid CONST key");
+                        assert_not_reached();
                 return token_match_string(token, val);
         }
         case TK_M_TAG:
@@ -2233,7 +2233,7 @@ static int udev_rule_apply_token_to_event(
                 /* do nothing for events. */
                 break;
         default:
-                assert_not_reached("Invalid token type");
+                assert_not_reached();
         }
 
         return true;
index 437ac9b832cd8e9ad462e857ceffe9f7030adaae..20820dd6472388eecab889dfac83620f658dc087 100644 (file)
@@ -171,7 +171,7 @@ int control_main(int argc, char *argv[], void *userdata) {
                 case '?':
                         return -EINVAL;
                 default:
-                        assert_not_reached("Unknown option.");
+                        assert_not_reached();
                 }
 
         if (optind < argc)
index 9414269fb80cbf6b381d2311db252b07de50a58b..e9db2847cf1f6d94c576ab855fb0b8a190195ba5 100644 (file)
@@ -71,7 +71,7 @@ static int parse_argv(int argc, char *argv[]) {
                 case '?':
                         return -EINVAL;
                 default:
-                        assert_not_reached("Unknown option");
+                        assert_not_reached();
                 }
 
         return 1;
index fa7f04f14ce8cda0721dd426fece6d2c550f2290..1ea89c16cc50cc95b0494aa5442e35cb3beac55e 100644 (file)
@@ -328,7 +328,7 @@ static int query_device(QueryType query, sd_device* device) {
                 return print_record(device);
         }
 
-        assert_not_reached("unknown query type");
+        assert_not_reached();
         return 0;
 }
 
@@ -456,7 +456,7 @@ int info_main(int argc, char *argv[], void *userdata) {
                 case '?':
                         return -EINVAL;
                 default:
-                        assert_not_reached("Unknown option");
+                        assert_not_reached();
                 }
 
         if (action == ACTION_DEVICE_ID_FILE) {
@@ -508,7 +508,7 @@ int info_main(int argc, char *argv[], void *userdata) {
                 else if (action == ACTION_ATTRIBUTE_WALK)
                         r = print_device_chain(device);
                 else
-                        assert_not_reached("Unknown action");
+                        assert_not_reached();
                 if (r < 0)
                         return r;
         }
index 00b03c550d568e9be1e9c6df52f818bce3c1050b..76aaf7c42e54b22ef8d6f1159df15d45855bee5b 100644 (file)
@@ -179,7 +179,7 @@ static int parse_argv(int argc, char *argv[]) {
                 case '?':
                         return -EINVAL;
                 default:
-                        assert_not_reached("Unknown option.");
+                        assert_not_reached();
                 }
 
         if (!arg_print_kernel && !arg_print_udev) {
index 2c61c2d8b02e920d2c60c3aaf9cbe749305b1f15..84b4f9ca45887a31bb1f08a6b2ca411a0a69da9c 100644 (file)
@@ -81,7 +81,7 @@ static int parse_argv(int argc, char *argv[]) {
                 case '?':
                         return -EINVAL;
                 default:
-                        assert_not_reached("Unknown option.");
+                        assert_not_reached();
                 }
         }
 
index 008d6f29143be7e0a9c1b9234bc75a9fab1e1bd2..992fc70807e931f84d1a020005dc8e93cf5a49ea 100644 (file)
@@ -45,7 +45,7 @@ static int parse_argv(int argc, char *argv[]) {
                 case '?':
                         return -EINVAL;
                 default:
-                        assert_not_reached("Unknown option");
+                        assert_not_reached();
                 }
 
         arg_command = argv[optind++];
index fbac719fa066a1955a6c97cc6883b41691bd7c05..f6ec22288403e28fb065ccc34dc78ce9232c7384 100644 (file)
@@ -81,7 +81,7 @@ static int parse_argv(int argc, char *argv[]) {
                 case '?':
                         return -EINVAL;
                 default:
-                        assert_not_reached("Unknown option");
+                        assert_not_reached();
                 }
 
         if (!argv[optind])
index 984ec1b84b25ea16a81be06cfef5661c71e32dc2..8acf3d9b118902db1ebc71d00dab6ad769cdee13 100644 (file)
@@ -416,7 +416,7 @@ int trigger_main(int argc, char *argv[], void *userdata) {
                 case '?':
                         return -EINVAL;
                 default:
-                        assert_not_reached("Unknown option");
+                        assert_not_reached();
                 }
         }
 
@@ -482,7 +482,7 @@ int trigger_main(int argc, char *argv[], void *userdata) {
                         return log_error_errno(r, "Failed to scan devices: %m");
                 break;
         default:
-                assert_not_reached("Unknown device type");
+                assert_not_reached();
         }
 
         r = exec_list(e, action, settle_hashmap);
index e55ae4bd54cca6064edc12f86459d84b5e2002ab..ba17d9348b6865947f039e426134bcf376c7b141 100644 (file)
@@ -77,7 +77,7 @@ static int parse_argv(int argc, char *argv[]) {
                         return -EINVAL;
 
                 default:
-                        assert_not_reached("Unhandled option");
+                        assert_not_reached();
                 }
 
         return 1; /* work to do */
index 13ac7c83b525d83f3d13f4dcad8e2fe066e16610..5a4657de14a81c6bb904d825f7fc48ca31bde6ef 100644 (file)
@@ -1663,7 +1663,7 @@ static int parse_argv(int argc, char *argv[]) {
                 case '?':
                         return -EINVAL;
                 default:
-                        assert_not_reached("Unhandled option");
+                        assert_not_reached();
 
                 }
         }
index 26b634ef5b4977e1fa07df182c1ddf658654f25b..c2312c790998d9f669d31acf3dabd32281722ae2 100644 (file)
@@ -52,7 +52,7 @@ int main(int argc, char *argv[]) {
                         return -EINVAL;
 
                 default:
-                        assert_not_reached("Unhandled option");
+                        assert_not_reached();
                 }
 
         device = argv[optind];
index 8db0c34fb5be8f11c3466862bd891020e5dc879c..af494d3075b2ad9ad6ec907fd040a3edc772d15f 100644 (file)
@@ -90,7 +90,7 @@ static int show_user(UserRecord *ur, Table *table) {
                 break;
 
         default:
-                assert_not_reached("Unexpected output mode");
+                assert_not_reached();
         }
 
         return 0;
@@ -240,7 +240,7 @@ static int show_group(GroupRecord *gr, Table *table) {
                 break;
 
         default:
-                assert_not_reached("Unexpected display mode");
+                assert_not_reached();
         }
 
         return 0;
@@ -384,7 +384,7 @@ static int show_membership(const char *user, const char *group, Table *table) {
                 break;
 
         default:
-                assert_not_reached("Unexpected output mode");
+                assert_not_reached();
         }
 
         return 0;
@@ -420,7 +420,7 @@ static int display_memberships(int argc, char *argv[], void *userdata) {
                                 if (r < 0)
                                         return log_error_errno(r, "Failed to enumerate groups of user: %m");
                         } else
-                                assert_not_reached("Unexpected verb");
+                                assert_not_reached();
 
                         for (;;) {
                                 _cleanup_free_ char *user = NULL, *group = NULL;
@@ -762,7 +762,7 @@ static int parse_argv(int argc, char *argv[]) {
                         return -EINVAL;
 
                 default:
-                        assert_not_reached("Unhandled option");
+                        assert_not_reached();
                 }
         }
 
index 8b7a20b08d4cb8c2dcd063fc90949cd6becb5f68..c3eb99ce9c190c248c3cb2ce2f832c65800a682b 100644 (file)
@@ -503,18 +503,16 @@ static int run(int argc, char *argv[]) {
 
                 n = now(CLOCK_MONOTONIC);
                 if (n >= usec_add(start_time, RUNTIME_MAX_USEC)) {
-                        char buf[FORMAT_TIMESPAN_MAX];
                         log_debug("Exiting worker, ran for %s, that's enough.",
-                                  format_timespan(buf, sizeof(buf), usec_sub_unsigned(n, start_time), 0));
+                                  FORMAT_TIMESPAN(usec_sub_unsigned(n, start_time), 0));
                         break;
                 }
 
                 if (last_busy_usec == USEC_INFINITY)
                         last_busy_usec = n;
                 else if (listen_idle_usec != USEC_INFINITY && n >= usec_add(last_busy_usec, listen_idle_usec)) {
-                        char buf[FORMAT_TIMESPAN_MAX];
                         log_debug("Exiting worker, been idle for %s.",
-                                  format_timespan(buf, sizeof(buf), usec_sub_unsigned(n, last_busy_usec), 0));
+                                  FORMAT_TIMESPAN(usec_sub_unsigned(n, last_busy_usec), 0));
                         break;
                 }
 
index 34208dcd87659e5da4501e169aa9856fd5344783..e58bae45d2293958c5bd4c7dcf6893dd02124b78 100644 (file)
@@ -30,7 +30,7 @@ static int help(void) {
 
         printf("%s attach VOLUME DATADEVICE HASHDEVICE ROOTHASH [OPTIONS]\n"
                "%s detach VOLUME\n\n"
-               "Attaches or detaches an integrity protected block device.\n"
+               "Attach or detach an integrity protected block device.\n"
                "\nSee the %s for details.\n",
                program_invocation_short_name,
                program_invocation_short_name,
@@ -130,7 +130,10 @@ static int run(int argc, char *argv[]) {
         _cleanup_(crypt_freep) struct crypt_device *cd = NULL;
         int r;
 
-        if (argc <= 1)
+        if (argc <= 1 ||
+            strv_contains(strv_skip(argv, 1), "--help") ||
+            strv_contains(strv_skip(argv, 1), "-h") ||
+            streq(argv[1], "help"))
                 return help();
 
         if (argc < 3)
index fe73bfe9db32864dea93f9cfd22c92b8271698ba..501cdca0b6e4d2351f083a06c8e3707b941e5bc7 100644 (file)
@@ -397,10 +397,11 @@ int xdg_autostart_format_exec_start(
         first_arg = true;
         for (i = n = 0; exec_split[i]; i++) {
                 _cleanup_free_ char *c = NULL, *raw = NULL, *p = NULL, *escaped = NULL, *quoted = NULL;
+                ssize_t l;
 
-                r = cunescape(exec_split[i], 0, &c);
-                if (r < 0)
-                        return log_debug_errno(r, "Failed to unescape '%s': %m", exec_split[i]);
+                l = cunescape(exec_split[i], 0, &c);
+                if (l < 0)
+                        return log_debug_errno(l, "Failed to unescape '%s': %m", exec_split[i]);
 
                 if (first_arg) {
                         _cleanup_free_ char *executable = NULL;
@@ -415,8 +416,7 @@ int xdg_autostart_format_exec_start(
                         if (!escaped)
                                 return log_oom();
 
-                        free(exec_split[n]);
-                        exec_split[n++] = TAKE_PTR(escaped);
+                        free_and_replace(exec_split[n++], escaped);
                         continue;
                 }
 
@@ -456,8 +456,7 @@ int xdg_autostart_format_exec_start(
                 if (!quoted)
                         return log_oom();
 
-                free(exec_split[n]);
-                exec_split[n++] = TAKE_PTR(quoted);
+                free_and_replace(exec_split[n++], quoted);
         }
         for (; exec_split[n]; n++)
                 exec_split[n] = mfree(exec_split[n]);
index 6f3db5955484836dd27a6434230747c9ff4d9e6a..b058f9364bee9e18ade68544d7f900d1044c1e05 100644 (file)
@@ -23,5 +23,5 @@ custom_target(
 
 if install_sysconfdir
         meson.add_install_script('sh', '-c',
-                                 mkdir_p.format(join_paths(sysconfdir, 'sysctl.d')))
+                                 mkdir_p.format(sysconfdir / 'sysctl.d'))
 endif
index 18db8d4284f319627c86f2e6cfd13dd546cf3062..352f00682b66dcfac7f4b6b14f3a7b92c62fd770 100755 (executable)
@@ -12,6 +12,11 @@ test_append_files() {
     (
         local workspace="${1:?}"
 
+        if selinuxenabled >/dev/null; then
+            dracut_install selinuxenabled
+            cp -ar /etc/selinux "$workspace/etc/selinux"
+        fi
+
         "$TEST_BASE_DIR/create-busybox-container" "$workspace/testsuite-13.nc-container"
         initdir="$workspace/testsuite-13.nc-container" dracut_install nc ip md5sum
     )
index 41c7e91917c560d25c13dc388190809007e3750e..6b77693346d8176bd60d433d6f17cf2818636ff3 100755 (executable)
@@ -11,7 +11,7 @@ TEST_NO_QEMU=1
 # Using timeout because if the test fails it can loop.
 # The reason is because the poweroff executed by end.service
 # could turn into a reboot if the test fails.
-NSPAWN_TIMEOUT=20
+NSPAWN_TIMEOUT=60
 
 # Remove this file if it exists. This is used along with
 # the make target "finish". Since concrete confirmation is
index 47c7f4d49a51a194ddee2f0e1fb3bbb2539e5f7d..a21230a4a8875d660cfc0b673c48aa4be1794f38 100644 (file)
@@ -140,12 +140,14 @@ if want_tests != 'false' and dmi_arches.contains(host_machine.cpu_family())
         endif
 
         foreach p : out.stdout().split()
-                source = join_paths(project_source_root, p)
+                source = project_source_root / p
                 name = 'dmidecode_' + p.split('/')[-1].split('.')[0]
 
                 test(name,
                      udev_dmi_memory_id_test,
-                     args : [dmi_memory_id_path, source, source + '.txt'])
+                     args : [udev_prog_paths['dmi_memory_id'],
+                             source,
+                             source + '.txt'])
         endforeach
 endif
 
index bef87ca91b2c9b9a9d1ecb0c25893e33a7bb966c..410b1699bf610e830d476e90210362b740890288 100644 (file)
@@ -35,6 +35,7 @@ QEMU_MEM="${QEMU_MEM:-512M}"
 # To force creating a new image from scratch (eg: to encrypt it), also define
 # TEST_FORCE_NEWIMAGE=1 in the test setup script.
 IMAGE_NAME=${IMAGE_NAME:-default}
+STRIP_BINARIES="${STRIP_BINARIES:-yes}"
 TEST_REQUIRE_INSTALL_TESTS="${TEST_REQUIRE_INSTALL_TESTS:-1}"
 TEST_PARALLELIZE="${TEST_PARALLELIZE:-0}"
 LOOPDEV=
@@ -228,7 +229,7 @@ is_built_with_asan() {
 
     # Borrowed from https://github.com/google/oss-fuzz/blob/cd9acd02f9d3f6e80011cc1e9549be526ce5f270/infra/base-images/base-runner/bad_build_check#L182
     local _asan_calls
-    _asan_calls="$(objdump -dC "$SYSTEMD_JOURNALD" | grep -E "callq?\s+[0-9a-f]+\s+<__asan" -c)"
+    _asan_calls="$(objdump -dC "$SYSTEMD_JOURNALD" | grep -E "(callq?|brasl?)\s+[^ <]+\s+<__asan" -c)"
     if ((_asan_calls < 1000)); then
         return 1
     else
@@ -416,7 +417,6 @@ run_qemu() {
         "loglevel=2"
         "init=$PATH_TO_INIT"
         "console=$CONSOLE"
-        "selinux=0"
         "SYSTEMD_UNIT_PATH=/usr/lib/systemd/tests/testdata/testsuite-$1.units:/usr/lib/systemd/tests/testdata/units:"
         "systemd.unit=testsuite.target"
         "systemd.wants=testsuite-$1.service"
diff --git a/test/test-network/conf/networkd-manage-foreign-routes-no.conf b/test/test-network/conf/networkd-manage-foreign-routes-no.conf
new file mode 100644 (file)
index 0000000..c75b8b4
--- /dev/null
@@ -0,0 +1,2 @@
+[Network]
+ManageForeignRoutes=no
index 4279b612d0f52f5c78033b8a193d8245ae351572..dc31d133c4e99c1489118df1b40de5ee73c58282 100755 (executable)
@@ -16,6 +16,7 @@ from shutil import copytree
 
 network_unit_file_path='/run/systemd/network'
 networkd_runtime_directory='/run/systemd/netif'
+networkd_conf_dropin_path='/run/systemd/networkd.conf.d'
 networkd_ci_path='/run/networkd-ci'
 network_sysctl_ipv6_path='/proc/sys/net/ipv6/conf'
 network_sysctl_ipv4_path='/proc/sys/net/ipv4/conf'
@@ -263,6 +264,7 @@ def setUpModule():
     global running_units
 
     os.makedirs(network_unit_file_path, exist_ok=True)
+    os.makedirs(networkd_conf_dropin_path, exist_ok=True)
     os.makedirs(networkd_ci_path, exist_ok=True)
 
     shutil.rmtree(networkd_ci_path)
@@ -460,6 +462,17 @@ def remove_unit_from_networkd_path(units):
             if (os.path.exists(os.path.join(network_unit_file_path, unit + '.d'))):
                 shutil.rmtree(os.path.join(network_unit_file_path, unit + '.d'))
 
+def copy_networkd_conf_dropin(*dropins):
+    """Copy networkd.conf dropin files into the testbed."""
+    for dropin in dropins:
+        shutil.copy(os.path.join(networkd_ci_path, dropin), networkd_conf_dropin_path)
+
+def remove_networkd_conf_dropin(dropins):
+    """Remove previously copied networkd.conf dropin files from the testbed."""
+    for dropin in dropins:
+        if (os.path.exists(os.path.join(networkd_conf_dropin_path, dropin))):
+            os.remove(os.path.join(networkd_conf_dropin_path, dropin))
+
 def start_dnsmasq(additional_options='', ipv4_range='192.168.5.10,192.168.5.200', ipv6_range='2600::10,2600::20', lease_time='1h'):
     dnsmasq_command = f'dnsmasq -8 /var/run/networkd-ci/test-dnsmasq-log-file --log-queries=extra --log-dhcp --pid-file=/var/run/networkd-ci/test-test-dnsmasq.pid --conf-file=/dev/null --interface=veth-peer --enable-ra --dhcp-range={ipv6_range},{lease_time} --dhcp-range={ipv4_range},{lease_time} -R --dhcp-leasefile=/var/run/networkd-ci/lease --dhcp-option=26,1492 --dhcp-option=option:router,192.168.5.1 --port=0 ' + additional_options
     check_output(dnsmasq_command)
@@ -1858,6 +1871,10 @@ class NetworkdNetworkTests(unittest.TestCase, Utilities):
         'routing-policy-rule-reconfigure2.network',
     ]
 
+    networkd_conf_dropins = [
+        'networkd-manage-foreign-routes-no.conf',
+    ]
+
     routing_policy_rule_tables = ['7', '8', '9', '10', '1011']
     routes = [['blackhole', '202.54.1.2'], ['unreachable', '202.54.1.3'], ['prohibit', '202.54.1.4']]
 
@@ -1875,6 +1892,7 @@ class NetworkdNetworkTests(unittest.TestCase, Utilities):
         remove_routes(self.routes)
         remove_links(self.links)
         remove_unit_from_networkd_path(self.units)
+        remove_networkd_conf_dropin(self.networkd_conf_dropins)
         stop_networkd(show_logs=True)
         call('ip netns del ns99', stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
 
@@ -2253,7 +2271,10 @@ class NetworkdNetworkTests(unittest.TestCase, Utilities):
         self.assertRegex(output, 'lookup 7')
         self.assertRegex(output, 'uidrange 100-200')
 
-    def test_route_static(self):
+    def _test_route_static(self, manage_foreign_routes):
+        if not manage_foreign_routes:
+            copy_networkd_conf_dropin('networkd-manage-foreign-routes-no.conf')
+
         copy_unit_to_networkd_unit_path('25-route-static.network', '12-dummy.netdev')
         start_networkd()
         self.wait_online(['dummy98:routable'])
@@ -2459,6 +2480,13 @@ class NetworkdNetworkTests(unittest.TestCase, Utilities):
         print(output)
         self.assertEqual(output, '')
 
+        self.tearDown()
+
+    def test_route_static(self):
+        for manage_foreign_routes in [True, False]:
+            with self.subTest(manage_foreign_routes=manage_foreign_routes):
+                self._test_route_static(manage_foreign_routes)
+
     @expectedFailureIfRTA_VIAIsNotSupported()
     def test_route_via_ipv6(self):
         copy_unit_to_networkd_unit_path('25-route-via-ipv6.network', '12-dummy.netdev')
@@ -3989,9 +4017,13 @@ class NetworkdDHCPClientTests(unittest.TestCase, Utilities):
         # Check UseGateway=
         if use_gateway and (not classless or not use_routes):
             self.assertRegex(output, r'default via 192.168.5.1 proto dhcp src 192.168.5.[0-9]* metric 1024')
-            self.assertRegex(output, r'192.168.5.1 proto dhcp scope link src 192.168.5.[0-9]* metric 1024')
         else:
             self.assertNotRegex(output, r'default via 192.168.5.1 proto dhcp src 192.168.5.[0-9]* metric 1024')
+
+        # Check route to gateway
+        if (use_gateway or dns_and_ntp_routes) and (not classless or not use_routes):
+            self.assertRegex(output, r'192.168.5.1 proto dhcp scope link src 192.168.5.[0-9]* metric 1024')
+        else:
             self.assertNotRegex(output, r'192.168.5.1 proto dhcp scope link src 192.168.5.[0-9]* metric 1024')
 
         # Check RoutesToDNS= and RoutesToNTP=
@@ -4001,12 +4033,9 @@ class NetworkdDHCPClientTests(unittest.TestCase, Utilities):
             if classless and use_routes:
                 self.assertRegex(output, r'8.8.8.8 via 192.168.5.4 proto dhcp src 192.168.5.[0-9]* metric 1024')
                 self.assertRegex(output, r'9.9.9.9 via 192.168.5.4 proto dhcp src 192.168.5.[0-9]* metric 1024')
-            elif use_gateway:
+            else:
                 self.assertRegex(output, r'8.8.8.8 via 192.168.5.1 proto dhcp src 192.168.5.[0-9]* metric 1024')
                 self.assertRegex(output, r'9.9.9.9 via 192.168.5.1 proto dhcp src 192.168.5.[0-9]* metric 1024')
-            else:
-                self.assertNotRegex(output, r'8.8.8.8 via 192.168.5.[0-9]* proto dhcp src 192.168.5.[0-9]* metric 1024')
-                self.assertNotRegex(output, r'9.9.9.9 via 192.168.5.[0-9]* proto dhcp src 192.168.5.[0-9]* metric 1024')
         else:
             self.assertNotRegex(output, r'192.168.5.10 proto dhcp scope link src 192.168.5.[0-9]* metric 1024')
             self.assertNotRegex(output, r'192.168.5.11 proto dhcp scope link src 192.168.5.[0-9]* metric 1024')
@@ -4397,9 +4426,24 @@ class NetworkdDHCPClientTests(unittest.TestCase, Utilities):
         start_dnsmasq()
         self.wait_online(['veth99:routable', 'veth-peer:routable'])
 
-        output = check_output('ip route list dev veth99 10.0.0.0/8')
+        output = check_output('ip route list dev veth99')
+        print(output)
+        self.assertRegex(output, 'default via 192.168.5.1 proto dhcp src 192.168.5.[0-9]*')
+        self.assertIn('10.0.0.0/8 via 192.168.5.1 proto dhcp', output)
+
+        with open(os.path.join(network_unit_file_path, 'dhcp-client-gateway-ipv4.network'), mode='a') as f:
+            f.write('[DHCPv4]\nUseGateway=no\n')
+
+        rc = call(*networkctl_cmd, 'reload', env=env)
+        self.assertEqual(rc, 0)
+
+        time.sleep(2)
+        self.wait_online(['veth99:routable', 'veth-peer:routable'])
+
+        output = check_output('ip route list dev veth99')
         print(output)
-        self.assertRegex(output, '10.0.0.0/8 via 192.168.5.1 proto dhcp')
+        self.assertNotRegex(output, 'default via 192.168.5.1 proto dhcp src 192.168.5.[0-9]*')
+        self.assertIn('10.0.0.0/8 via 192.168.5.1 proto dhcp', output)
 
     def test_dhcp_client_gateway_ipv6(self):
         copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-server-veth-peer.network',
index 0d468b2db1748ec74b8a0ab773062f2f1e0814c8..8f3c0b2df83df90d08a728b7b1cd97e531cc22cc 100755 (executable)
@@ -115,6 +115,16 @@ EOF
     return "$(systemctl show -P ExecMainStatus nspawn_machinectl_bind.service)"
 }
 
+function check_selinux {
+    if ! selinuxenabled; then
+        echo >&2 "SELinux is not enabled, skipping SELinux-related tests"
+        return 0
+    fi
+
+    # Basic test coverage to avoid issues like https://github.com/systemd/systemd/issues/19976
+    systemd-nspawn "${SUSE_OPTS[@]}" --register=no -b -D /testsuite-13.nc-container --selinux-apifs-context=system_u:object_r:container_file_t:s0:c0,c1 --selinux-context=system_u:system_r:container_t:s0:c0,c1
+}
+
 function run {
     if [[ "$1" = "yes" && "$is_v2_supported" = "no" ]]; then
         printf "Unified cgroup hierarchy is not supported. Skipping.\n" >&2
@@ -199,4 +209,6 @@ done
 
 check_machinectl_bind
 
+check_selinux
+
 touch /testok
index 94fd927a5d13c16446ea2cecda574f3f1df2e33e..b684011785feeab1df629c5b9723208096786aef 100755 (executable)
@@ -34,8 +34,9 @@ journalCursorFile="jounalCursorFile"
 
 startStrace() {
     coproc strace -qq -p 1 -o "$straceLog" -e set_mempolicy -s 1024 ${1:+"$1"}
-    # Wait for strace to properly "initialize"
-    sleep $sleepAfterStart
+    # Wait for strace to properly "initialize", i.e. until PID 1 has the TracerPid
+    # field set to the current strace's PID
+    while ! awk -v spid="$COPROC_PID" '/^TracerPid:/ {exit !($2 == spid);}' /proc/1/status; do sleep 0.1; done
 }
 
 stopStrace() {
index 63549c8a7850a5fec986e39d7007d1dd33fca1df..099ecc98fae838902e40547abbb131008ee41da3 100755 (executable)
@@ -21,7 +21,17 @@ fi
 
 rm -rf /etc/systemd/system/testsuite-55-testbloat.service.d
 
-echo "DefaultMemoryPressureDurationSec=5s" >>/etc/systemd/oomd.conf
+echo "DefaultMemoryPressureDurationSec=2s" >>/etc/systemd/oomd.conf
+
+mkdir -p /etc/systemd/system/systemd-oomd.service.d/
+echo -e "[Service]\nEnvironment=SYSTEMD_LOG_LEVEL=debug" >/etc/systemd/system/systemd-oomd.service.d/debug.conf
+
+systemctl daemon-reload
+
+# if oomd is already running for some reasons, then restart it to make sure the above settings to be applied
+if systemctl is-active systemd-oomd.service; then
+    systemctl restart systemd-oomd.service
+fi
 
 systemctl start testsuite-55-testchill.service
 systemctl start testsuite-55-testbloat.service
@@ -29,16 +39,18 @@ systemctl start testsuite-55-testbloat.service
 # Verify systemd-oomd is monitoring the expected units
 oomctl | grep "/testsuite-55-workload.slice"
 oomctl | grep "1.00%"
-oomctl | grep "Default Memory Pressure Duration: 5s"
+oomctl | grep "Default Memory Pressure Duration: 2s"
+
+systemctl status testsuite-55-testchill.service
 
-# systemd-oomd watches for elevated pressure for 5 seconds before acting.
+# systemd-oomd watches for elevated pressure for 2 seconds before acting.
 # It can take time to build up pressure so either wait 2 minutes or for the service to fail.
 timeout="$(date -ud "2 minutes" +%s)"
 while [[ $(date -u +%s) -le $timeout ]]; do
     if ! systemctl status testsuite-55-testbloat.service; then
         break
     fi
-    sleep 5
+    sleep 2
 done
 
 # testbloat should be killed and testchill should be fine
index 8158754667626c3f7d3f417a21deb00227de8a20..06526776fdbef21c96b5ed34a3370c86cab95c27 100755 (executable)
@@ -26,6 +26,7 @@ done
 
 # figure out if we have entered the rate limit state
 
+entered_rl=0
 exited_rl=0
 timeout="$(date -ud "2 minutes" +%s)"
 while [[ $(date -u +%s) -le ${timeout} ]]; do
similarity index 90%
rename from tmpfiles.d/legacy.conf
rename to tmpfiles.d/legacy.conf.in
index 62e2ae0986234974d4bb89997f3ca73fda7144a6..4f2c0d7c4310aeea4d75b7c416c81ad63777cf37 100644 (file)
@@ -12,6 +12,9 @@
 
 d /run/lock 0755 root root -
 L /var/lock - - - - ../run/lock
+{% if CREATE_LOG_DIRS %}
+L /var/log/README - - - - ../..{{DOC_DIR}}/README.logs
+{% endif %}
 
 # /run/lock/subsys is used for serializing SysV service execution, and
 # hence without use on SysV-less systems.
index a8aaacaf29e9f67d08429acb5b1029dd39e86533..de36f5743d0921b11665fba1b9e29e70e871c2bd 100644 (file)
@@ -12,7 +12,6 @@ files = [['README',               ''],
          ['systemd-pstore.conf',  'ENABLE_PSTORE'],
          ['tmp.conf',             ''],
          ['x11.conf',             ''],
-         ['legacy.conf',          'HAVE_SYSV_COMPAT'],
         ]
 
 foreach pair : files
@@ -26,25 +25,32 @@ foreach pair : files
         endif
 endforeach
 
-in_files = ['etc.conf',
-            'static-nodes-permissions.conf',
-            'systemd.conf',
-            'var.conf']
+in_files = [['etc.conf',                      ''],
+            ['legacy.conf',                   'HAVE_SYSV_COMPAT'],
+            ['static-nodes-permissions.conf', ''],
+            ['systemd.conf',                  ''],
+            ['var.conf',                      ''],
+           ]
 
-foreach file : in_files
-        custom_target(
-                # XXX: workaround for old meson. Drop when upgrading.
-                'tmpfiles+' + file,
-                input : file + '.in',
-                output: file,
-                command : [meson_render_jinja2, config_h, '@INPUT@'],
-                capture : true,
-                install : enable_tmpfiles,
-                install_dir : tmpfilesdir)
+foreach pair : in_files
+        if not enable_tmpfiles
+                # do nothing
+        elif pair[1] == '' or conf.get(pair[1]) == 1
+                custom_target(
+                        pair[0],
+                        input : pair[0] + '.in',
+                        output: pair[0],
+                        command : [meson_render_jinja2, config_h, '@INPUT@'],
+                        capture : true,
+                        install : enable_tmpfiles,
+                        install_dir : tmpfilesdir)
+        else
+                message('Not installing tmpfiles.d/@0@ because @1@ is @2@'
+                        .format(pair[0], pair[1], conf.get(pair[1], 0)))
+        endif
 endforeach
 
 if enable_tmpfiles and install_sysconfdir
         meson.add_install_script(
-                'sh', '-c',
-                mkdir_p.format(join_paths(sysconfdir, 'tmpfiles.d')))
+                'sh', '-c', mkdir_p.format(sysconfdir / 'tmpfiles.d'))
 endif
index 4b680d28025837cee36ccdc6bc786017eba0a75d..f0756b4e45bb7fe2ea5811bfd2973a3cc0c95ed8 100755 (executable)
@@ -4,5 +4,6 @@ set -eu
 
 tag="$(git describe --abbrev=0 --match 'v[0-9][0-9][0-9]')"
 git log --pretty=tformat:%aN --author=noreply@weblate.org --invert-grep -s "${tag}.." | \
-    sed 's/ / /g; s/--/-/g; s/.*/        \0,/' |
-    sort -u
+    sed 's/ / /g; s/--/-/g; s/.*/\0,/' |
+    sort -u | tr '\n' ' ' | sed -e "s/^/Contributions from: /g" -e "s/,\s*$/\n/g" | fold -w 72 -s | \
+    sed -e "s/^/        /g" -e "s/\s*$//g"
index 17e9ead9c19a1079accc28667249a8d286794f4f..64da9efaafbf1cb8dd906b26392001dd67979186 100644 (file)
@@ -307,17 +307,17 @@ install_data('user-.slice.d/10-defaults.conf',
 
 if install_sysconfdir
         meson.add_install_script(meson_make_symlink,
-                                 join_paths(pkgsysconfdir, 'user'),
-                                 join_paths(sysconfdir, 'xdg/systemd/user'))
+                                 pkgsysconfdir / 'user',
+                                 sysconfdir / 'xdg/systemd/user')
 endif
 meson.add_install_script(meson_make_symlink,
-                         join_paths(dbussystemservicedir, 'org.freedesktop.systemd1.service'),
-                         join_paths(dbussessionservicedir, 'org.freedesktop.systemd1.service'))
+                         dbussystemservicedir / 'org.freedesktop.systemd1.service',
+                         dbussessionservicedir / 'org.freedesktop.systemd1.service')
 if conf.get('HAVE_SYSV_COMPAT') == 1
         foreach i : [1, 2, 3, 4, 5]
                 meson.add_install_script(
                         'sh', '-c',
-                        mkdir_p.format(join_paths(systemunitdir, 'runlevel@0@.target.wants'.format(i))))
+                        mkdir_p.format(systemunitdir / 'runlevel@0@.target.wants'.format(i)))
         endforeach
 endif
 
diff --git a/units/systemd-boot-update.service b/units/systemd-boot-update.service
new file mode 100644 (file)
index 0000000..61ff127
--- /dev/null
@@ -0,0 +1,24 @@
+#  SPDX-License-Identifier: LGPL-2.1-or-later
+#
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+[Unit]
+Description=Automatic Boot Loader Update
+Documentation=man:bootctl(1)
+DefaultDependencies=no
+Conflicts=shutdown.target
+After=local-fs.target
+Before=sysinit.target shutdown.target systemd-update-done.service
+
+[Service]
+Type=oneshot
+RemainAfterExit=yes
+ExecStart=bootctl --no-variables --graceful update
+
+[Install]
+WantedBy=sysinit.target
index 678bbab65c464b145c8ba9210c4373e3ee2d376d..0576f84697423b4a9d2e7abeb154fffb25cf2521 100644 (file)
@@ -20,6 +20,7 @@ CapabilityBoundingSet=CAP_SYS_ADMIN CAP_CHOWN CAP_DAC_OVERRIDE CAP_FOWNER CAP_FS
 DeviceAllow=/dev/loop-control rw
 DeviceAllow=/dev/mapper/control rw
 DeviceAllow=block-* rw
+DeviceAllow=char-hidraw rw
 ExecStart={{ROOTLIBEXECDIR}}/systemd-homed
 IPAddressDeny=any
 KillMode=mixed