1
0
mirror of https://github.com/systemd/systemd synced 2025-09-22 13:24:45 +02:00

Compare commits

...

20 Commits

Author SHA1 Message Date
Eric Anderson
9e12d5bf63 socket-proxy: Support exit-on-idle
This adds the --exit-idle-time argument that causes
systemd-socket-proxyd to exit when there has been an idle period. An
open connection prevents the idle period from starting, even if there is
no activity on that connection.

When combined with another service that uses StopWhenUnneeded=, the
proxy exiting can trigger a resource-intensive process to exit. So
although the proxy may consume minimal resources, significant resources
can be saved indirectly.

Fixes #2106
2020-05-06 13:58:57 +02:00
Gergely Polonkai
c28904dae0 Update the rsync command in CONVERTING_TO_HOMED
The old version of this command will delete everything under the new home directory (including `.identity`), rendering the directory unusable with homed.
2020-05-06 10:52:22 +02:00
Daan De Meyer
eff7c2d3c9 sd-bus: Add a nicer way of specifying sd-bus vtable method arguments
SD_BUS_NAMES_WITH_ARGS is a less error-prone way of specifying D-Bus
method arguments.
2020-05-06 10:22:54 +02:00
Evgeny Vereshchagin
7f3a5eb70e build-system: bring back 'nonnull'
Having taken a look at https://github.com/systemd/systemd/runs/645252074?check_suite_focus=true
where fuzz-journal-remote failed with
```
AddressSanitizer:DEADLYSIGNAL
=================================================================
==16==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000000 (pc 0x7f864f98948e bp 0x7ffde5c6b7c0 sp 0x7ffde5c6b560 T0)
==16==The signal is caused by a READ memory access.
==16==Hint: address points to the zero page.
SCARINESS: 10 (null-deref)
    #0 0x7f864f98948e in output_short /work/build/../../src/systemd/src/shared/logs-show.c
    #1 0x7f864f984624 in show_journal_entry /work/build/../../src/systemd/src/shared/logs-show.c:1154:15
    #2 0x7f864f984b63 in show_journal /work/build/../../src/systemd/src/shared/logs-show.c:1239:21
    #3 0x4cabab in LLVMFuzzerTestOneInput /work/build/../../src/systemd/src/fuzz/fuzz-journal-remote.c:67:21
    #4 0x51fd16 in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, unsigned long) /src/libfuzzer/FuzzerLoop.cpp:556:15
    #5 0x51c330 in fuzzer::Fuzzer::RunOne(unsigned char const*, unsigned long, bool, fuzzer::InputInfo*, bool*) /src/libfuzzer/FuzzerLoop.cpp:470:3
    #6 0x523700 in fuzzer::Fuzzer::ReadAndExecuteSeedCorpora(std::__1::vector<fuzzer::SizedFile, fuzzer::fuzzer_allocator<fuzzer::SizedFile> >&) /src/libfuzzer/FuzzerLoop.cpp:765:7
    #7 0x5246cd in fuzzer::Fuzzer::Loop(std::__1::vector<fuzzer::SizedFile, fuzzer::fuzzer_allocator<fuzzer::SizedFile> >&) /src/libfuzzer/FuzzerLoop.cpp:792:3
    #8 0x4de3d1 in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long)) /src/libfuzzer/FuzzerDriver.cpp:824:6
    #9 0x4cfb47 in main /src/libfuzzer/FuzzerMain.cpp:19:10
    #10 0x7f864e69782f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2082f)
    #11 0x41f2a8 in _start (out/fuzz-journal-remote+0x41f2a8)

AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV /work/build/../../src/systemd/src/shared/logs-show.c in output_short
==16==ABORTING
MS: 0 ; base unit: 0000000000000000000000000000000000000000
0x44,0x3d,0xa,0x5f,0x5f,0x52,0x45,0x41,0x4c,0x54,0x49,0x4d,0x45,0x5f,0x54,0x49,0x4d,0x45,0x53,0x54,0x41,0x4d,0x50,0x3d,0x31,0xa,0xa,
D=\x0a__REALTIME_TIMESTAMP=1\x0a\x0a
artifact_prefix='./'; Test unit written to ./crash-d635b9dd31cceff3c912fd45e1a58d7e90f0ad73
Base64: RD0KX19SRUFMVElNRV9USU1FU1RBTVA9MQoK
```
I was wondering why it hadn't been caught by the compiler even though clang should have failed to compile it with
```
../src/shared/logs-show.c:624:25: warning: null passed to a callee that requires a non-null argument [-Wnonnull]
                        print_multiline(f, 4 + fieldlen + 1, 0, OUTPUT_FULL_WIDTH, 0, false,
                        ^
../src/shared/logs-show.c:161:24: note: callee declares array parameter as static here
                size_t highlight[static 2]) {
                       ^        ~~~~~~~~~~
../src/shared/logs-show.c:1239:21: warning: null passed to a callee that requires a non-null argument [-Wnonnull]
                r = show_journal_entry(f, j, mode, n_columns, flags, NULL, NULL, ellipsized);
                    ^                                                      ~~~~
../src/shared/logs-show.c:1133:30: note: callee declares array parameter as static here
                const size_t highlight[static 2],
                             ^        ~~~~~~~~~~
2 warnings generated.
```

Given that judging by https://github.com/systemd/systemd/issues/13039 it doesn't seem to be
the first time issues like that have been missed I think it would be better to turn nonnull on
and get around false positives on a case-by-case basis with DISABLE_WARNING_NONNULL .. REENABLE_WARNING

Reopens https://github.com/systemd/systemd/issues/6119
2020-05-06 09:50:57 +02:00
Lennart Poettering
fc58c0c7bf sysusers: be extra careful when locking accounts
Let's use "!*" instead of "!!" as invalid password string.

Generally, any invalid password string can be used to for locking an
account, according to shadow(5). To temporarily lock a password of an
account it is commonly implemented to prefix the original password with
a single "!", so that it can later on be unlocked again by removing the
"!", restoring the original password. Thus, the "!" marker is an
indicator for a locked password; the act of prefixing "!" to a
password string is the locking operation; and the removal of a "!"
prefix is the unlock operation. (This is also suggested in shadow(5)).

If we want to entirely lock an account we previously used "!!" as
password string. This is nice since it indicates the password is locked.
However, it is less than ideal, since applying the password unlock
operation once will change the string to "!", which is still a locked
password. Unlocking the password a second time will result in "", i.e.
the empty password, which will in many cases allow logging in without
password. And that's a problem. Hopefully, tools do not allow such
duplicate unlocking, but it's still not a nice property.

By changing our password string to "!*" we get different behaviour: the
password will appear locked. When it is unlocked the password is "*"
which is an invalid password. In that case the password is hence
unlocked but invalid, which is a much better state to be in than the
above.

This is paranoia hardening. Not more. There's no report that anyone
every unlocked an account twice and people could log in.
2020-05-06 09:44:35 +02:00
Lennart Poettering
c92391f52f
Merge pull request #15692 from keszybz/preset-cleanup
Make systemctl list-unit-files output more useful
2020-05-06 08:19:37 +02:00
Zbigniew Jędrzejewski-Szmek
31b8895af7 systemctl: do not show preset state for "static"/"alias"/"generated"/"transient" units
This modifies list-unit-files and status.

The output of list-unit-files would contain various lines with "static
disabled", which is just misleading, because systemctl preset will not touch
those files, so the preset configuration is not relevant. Similarly, for
"generated" and "transient" units, preset state is irrelevant. For "alias"
lines, the preset for the alias target would be used. In all cases let's just
skip preset status in those cases.

Diff for a a Fedora rawhide container:

--- $ systemctl --root=/tmp/root2 list-unit-files
+++ $ build/systemctl --root=/tmp/root2 list-unit-files
@@ -1,125 +1,125 @@
 UNIT FILE                                  STATE    VENDOR PRESET
-proc-sys-fs-binfmt_misc.automount          static   disabled
-dev-hugepages.mount                        static   disabled
-dev-mqueue.mount                           static   disabled
-proc-fs-nfsd.mount                         static   disabled
+proc-sys-fs-binfmt_misc.automount          static
+dev-hugepages.mount                        static
+dev-mqueue.mount                           static
+proc-fs-nfsd.mount                         static
 proc-sys-fs-binfmt_misc.mount              disabled disabled
-sys-fs-fuse-connections.mount              static   disabled
-sys-kernel-config.mount                    static   disabled
-sys-kernel-debug.mount                     static   disabled
-sys-kernel-tracing.mount                   static   disabled
-tmp.mount                                  static   disabled
-var-lib-nfs-rpc_pipefs.mount               static   disabled
+sys-fs-fuse-connections.mount              static
+sys-kernel-config.mount                    static
+sys-kernel-debug.mount                     static
+sys-kernel-tracing.mount                   static
+tmp.mount                                  static
+var-lib-nfs-rpc_pipefs.mount               static
 ostree-finalize-staged.path                disabled enabled
-systemd-ask-password-console.path          static   disabled
-systemd-ask-password-plymouth.path         static   disabled
-systemd-ask-password-wall.path             static   disabled
+systemd-ask-password-console.path          static
+systemd-ask-password-plymouth.path         static
+systemd-ask-password-wall.path             static
 abrt-journal-core.service                  enabled  enabled
 abrt-oops.service                          enabled  enabled
 abrt-pstoreoops.service                    disabled disabled
 abrt-vmcore.service                        enabled  enabled
 abrt-xorg.service                          enabled  enabled
 abrtd.service                              enabled  enabled
-anaconda-direct.service                    static   disabled
-anaconda-nm-config.service                 static   disabled
-anaconda-noshell.service                   static   disabled
-anaconda-pre.service                       static   disabled
-anaconda-shell@.service                    static   disabled
-anaconda-sshd.service                      static   disabled
-anaconda-tmux@.service                     static   disabled
-anaconda.service                           static   disabled
+anaconda-direct.service                    static
+anaconda-nm-config.service                 static
+anaconda-noshell.service                   static
+anaconda-pre.service                       static
+anaconda-shell@.service                    static
+anaconda-sshd.service                      static
+anaconda-tmux@.service                     static
+anaconda.service                           static
 arp-ethers.service                         disabled disabled
 atd.service                                enabled  enabled
 auditd.service                             enabled  enabled
-auth-rpcgss-module.service                 static   disabled
+auth-rpcgss-module.service                 static
 autofs.service                             disabled disabled
-autovt@.service                            enabled  disabled
-blivet.service                             static   disabled
+autovt@.service                            alias
+blivet.service                             static
 blk-availability.service                   disabled disabled
 bluetooth.service                          enabled  enabled
-btattach-bcm@.service                      static   disabled
+btattach-bcm@.service                      static
 certmonger.service                         disabled disabled
-chrony-dnssrv@.service                     static   disabled
+chrony-dnssrv@.service                     static
 chrony-wait.service                        disabled disabled
 chronyd.service                            enabled  enabled
-clean-mount-point@.service                 static   disabled
-cockpit-motd.service                       static   disabled
-cockpit-wsinstance-http-redirect.service   static   disabled
-cockpit-wsinstance-http.service            static   disabled
-cockpit-wsinstance-https-factory@.service  static   disabled
-cockpit-wsinstance-https@.service          static   disabled
-cockpit.service                            static   disabled
+clean-mount-point@.service                 static
+cockpit-motd.service                       static
+cockpit-wsinstance-http-redirect.service   static
+cockpit-wsinstance-http.service            static
+cockpit-wsinstance-https-factory@.service  static
+cockpit-wsinstance-https@.service          static
+cockpit.service                            static
 console-getty.service                      disabled disabled
-container-getty@.service                   static   disabled
+container-getty@.service                   static
 dbus-broker.service                        enabled  enabled
 dbus-daemon.service                        disabled disabled
-dbus-org.bluez.service                     enabled  disabled
-dbus-org.fedoraproject.FirewallD1.service  enabled  disabled
-dbus-org.freedesktop.home1.service         static   disabled
-dbus-org.freedesktop.hostname1.service     static   disabled
-dbus-org.freedesktop.locale1.service       static   disabled
-dbus-org.freedesktop.login1.service        static   disabled
-dbus-org.freedesktop.ModemManager1.service enabled  disabled
-dbus-org.freedesktop.nm-dispatcher.service enabled  disabled
-dbus-org.freedesktop.portable1.service     static   disabled
-dbus-org.freedesktop.timedate1.service     static   disabled
-dbus.service                               enabled  disabled
+dbus-org.bluez.service                     alias
+dbus-org.fedoraproject.FirewallD1.service  alias
+dbus-org.freedesktop.home1.service         alias
+dbus-org.freedesktop.hostname1.service     alias
+dbus-org.freedesktop.locale1.service       alias
+dbus-org.freedesktop.login1.service        alias
+dbus-org.freedesktop.ModemManager1.service alias
+dbus-org.freedesktop.nm-dispatcher.service alias
+dbus-org.freedesktop.portable1.service     alias
+dbus-org.freedesktop.timedate1.service     alias
+dbus.service                               alias
 dbxtool.service                            enabled  enabled
 debug-shell.service                        disabled disabled
-dm-event.service                           static   enabled
+dm-event.service                           static
 dmraid-activation.service                  enabled  enabled
-dnf-makecache.service                      static   disabled
+dnf-makecache.service                      static
 dnsmasq.service                            disabled disabled
-dracut-cmdline.service                     static   disabled
-dracut-initqueue.service                   static   disabled
-dracut-mount.service                       static   disabled
-dracut-pre-mount.service                   static   disabled
-dracut-pre-pivot.service                   static   disabled
-dracut-pre-trigger.service                 static   disabled
-dracut-pre-udev.service                    static   disabled
-dracut-shutdown.service                    static   disabled
+dracut-cmdline.service                     static
+dracut-initqueue.service                   static
+dracut-mount.service                       static
+dracut-pre-mount.service                   static
+dracut-pre-pivot.service                   static
+dracut-pre-trigger.service                 static
+dracut-pre-udev.service                    static
+dracut-shutdown.service                    static
 ead.service                                disabled disabled
-emergency.service                          static   disabled
+emergency.service                          static
 fancontrol.service                         disabled disabled
 firewalld.service                          enabled  enabled
-fprintd.service                            static   disabled
-fstrim.service                             static   disabled
+fprintd.service                            static
+fstrim.service                             static
 getty@.service                             enabled  enabled
-grub-boot-indeterminate.service            static   disabled
+grub-boot-indeterminate.service            static
 gssproxy.service                           disabled disabled
 import-state.service                       enabled  enabled
 initial-setup-reconfiguration.service      disabled disabled
 initial-setup.service                      enabled  disabled
-initrd-cleanup.service                     static   disabled
-initrd-parse-etc.service                   static   disabled
-initrd-switch-root.service                 static   disabled
-initrd-udevadm-cleanup-db.service          static   disabled
-instperf.service                           static   disabled
+initrd-cleanup.service                     static
+initrd-parse-etc.service                   static
+initrd-switch-root.service                 static
+initrd-udevadm-cleanup-db.service          static
+instperf.service                           static
 io.podman.service                          disabled disabled
 irqbalance.service                         enabled  enabled
-iscsi-shutdown.service                     static   disabled
+iscsi-shutdown.service                     static
 iscsi.service                              enabled  disabled
 iscsid.service                             disabled disabled
 iscsiuio.service                           disabled disabled
 iwd.service                                disabled disabled
 kdump.service                              disabled disabled
-kmod-static-nodes.service                  static   disabled
-ldconfig.service                           static   disabled
+kmod-static-nodes.service                  static
+ldconfig.service                           static
 lm_sensors.service                         enabled  enabled
 loadmodules.service                        disabled disabled
-logrotate.service                          static   disabled
-lvm2-lvmpolld.service                      static   enabled
+logrotate.service                          static
+lvm2-lvmpolld.service                      static
 lvm2-monitor.service                       enabled  enabled
-lvm2-pvscan@.service                       static   disabled
-man-db-cache-update.service                static   disabled
+lvm2-pvscan@.service                       static
+man-db-cache-update.service                static
 man-db-restart-cache-update.service        disabled disabled
-mdadm-grow-continue@.service               static   disabled
-mdadm-last-resort@.service                 static   disabled
-mdmon@.service                             static   disabled
+mdadm-grow-continue@.service               static
+mdadm-last-resort@.service                 static
+mdmon@.service                             static
 mdmonitor.service                          enabled  enabled
-mlocate-updatedb.service                   static   disabled
+mlocate-updatedb.service                   static
 ModemManager.service                       enabled  enabled
-modprobe@.service                          static   disabled
+modprobe@.service                          static
 multipathd.service                         enabled  enabled
 ndctl-monitor.service                      disabled disabled
 NetworkManager-dispatcher.service          enabled  enabled
@@ -127,53 +127,53 @@
 NetworkManager.service                     enabled  enabled
 nfs-blkmap.service                         disabled disabled
 nfs-convert.service                        enabled  disabled
-nfs-idmapd.service                         static   disabled
-nfs-mountd.service                         static   disabled
+nfs-idmapd.service                         static
+nfs-mountd.service                         static
 nfs-server.service                         disabled disabled
-nfs-utils.service                          static   disabled
-nfsdcld.service                            static   disabled
+nfs-utils.service                          static
+nfsdcld.service                            static
 nftables.service                           disabled disabled
 nis-domainname.service                     disabled disabled
 oddjobd.service                            disabled disabled
 openhpid.service                           disabled disabled
-ostree-finalize-staged.service             static   disabled
-ostree-prepare-root.service                static   disabled
+ostree-finalize-staged.service             static
+ostree-prepare-root.service                static
 ostree-remount.service                     enabled  enabled
-packagekit-offline-update.service          static   disabled
-packagekit.service                         static   disabled
+packagekit-offline-update.service          static
+packagekit.service                         static
 pcscd.service                              indirect disabled
-plymouth-halt.service                      static   disabled
-plymouth-kexec.service                     static   disabled
-plymouth-poweroff.service                  static   disabled
-plymouth-quit-wait.service                 static   disabled
-plymouth-quit.service                      static   disabled
-plymouth-read-write.service                static   disabled
-plymouth-reboot.service                    static   disabled
-plymouth-start.service                     static   disabled
-plymouth-switch-root.service               static   disabled
+plymouth-halt.service                      static
+plymouth-kexec.service                     static
+plymouth-poweroff.service                  static
+plymouth-quit-wait.service                 static
+plymouth-quit.service                      static
+plymouth-read-write.service                static
+plymouth-reboot.service                    static
+plymouth-start.service                     static
+plymouth-switch-root.service               static
 podman.service                             disabled disabled
-polkit.service                             static   enabled
+polkit.service                             static
 psacct.service                             disabled disabled
 qemu-guest-agent.service                   enabled  enabled
-quotaon.service                            static   disabled
+quotaon.service                            static
 raid-check.service                         disabled disabled
-rc-local.service                           static   disabled
+rc-local.service                           static
 rdisc.service                              disabled disabled
-realmd.service                             static   disabled
-rescue.service                             static   disabled
+realmd.service                             static
+rescue.service                             static
 rngd.service                               enabled  enabled
-rpc-gssd.service                           static   disabled
-rpc-statd-notify.service                   static   disabled
-rpc-statd.service                          static   disabled
+rpc-gssd.service                           static
+rpc-statd-notify.service                   static
+rpc-statd.service                          static
 rpcbind.service                            disabled disabled
 rsyslog.service                            enabled  enabled
 selinux-autorelabel-mark.service           enabled  enabled
-selinux-autorelabel.service                static   disabled
+selinux-autorelabel.service                static
 serial-getty@.service                      disabled disabled
 smartd.service                             enabled  enabled
 sshd-keygen@.service                       disabled disabled
 sshd.service                               enabled  enabled
-sshd@.service                              static   disabled
+sshd@.service                              static
 sssd-autofs.service                        indirect disabled
 sssd-kcm.service                           indirect disabled
 sssd-nss.service                           indirect disabled
@@ -182,84 +182,84 @@
 sssd-ssh.service                           indirect disabled
 sssd-sudo.service                          indirect disabled
 sssd.service                               enabled  enabled
-system-update-cleanup.service              static   disabled
-systemd-ask-password-console.service       static   disabled
-systemd-ask-password-plymouth.service      static   disabled
-systemd-ask-password-wall.service          static   disabled
-systemd-backlight@.service                 static   disabled
-systemd-binfmt.service                     static   disabled
-systemd-bless-boot.service                 static   disabled
+system-update-cleanup.service              static
+systemd-ask-password-console.service       static
+systemd-ask-password-plymouth.service      static
+systemd-ask-password-wall.service          static
+systemd-backlight@.service                 static
+systemd-binfmt.service                     static
+systemd-bless-boot.service                 static
 systemd-boot-check-no-failures.service     disabled disabled
-systemd-boot-system-token.service          static   disabled
-systemd-coredump@.service                  static   disabled
-systemd-exit.service                       static   disabled
-systemd-firstboot.service                  static   disabled
-systemd-fsck-root.service                  static   disabled
-systemd-fsck@.service                      static   disabled
-systemd-halt.service                       static   disabled
-systemd-hibernate-resume@.service          static   disabled
-systemd-hibernate.service                  static   disabled
-systemd-homed.service                      static   disabled
-systemd-hostnamed.service                  static   disabled
-systemd-hwdb-update.service                static   disabled
-systemd-hybrid-sleep.service               static   disabled
-systemd-initctl.service                    static   disabled
-systemd-journal-catalog-update.service     static   disabled
-systemd-journal-flush.service              static   disabled
-systemd-journald.service                   static   disabled
-systemd-journald@.service                  static   disabled
-systemd-kexec.service                      static   disabled
-systemd-localed.service                    static   disabled
-systemd-logind.service                     static   disabled
-systemd-machine-id-commit.service          static   disabled
-systemd-modules-load.service               static   disabled
+systemd-boot-system-token.service          static
+systemd-coredump@.service                  static
+systemd-exit.service                       static
+systemd-firstboot.service                  static
+systemd-fsck-root.service                  static
+systemd-fsck@.service                      static
+systemd-halt.service                       static
+systemd-hibernate-resume@.service          static
+systemd-hibernate.service                  static
+systemd-homed.service                      static
+systemd-hostnamed.service                  static
+systemd-hwdb-update.service                static
+systemd-hybrid-sleep.service               static
+systemd-initctl.service                    static
+systemd-journal-catalog-update.service     static
+systemd-journal-flush.service              static
+systemd-journald.service                   static
+systemd-journald@.service                  static
+systemd-kexec.service                      static
+systemd-localed.service                    static
+systemd-logind.service                     static
+systemd-machine-id-commit.service          static
+systemd-modules-load.service               static
 systemd-network-generator.service          disabled disabled
 systemd-networkd-wait-online.service       disabled disabled
 systemd-networkd.service                   disabled disabled
-systemd-portabled.service                  static   disabled
-systemd-poweroff.service                   static   disabled
+systemd-portabled.service                  static
+systemd-poweroff.service                   static
 systemd-pstore.service                     disabled enabled
-systemd-quotacheck.service                 static   disabled
-systemd-random-seed.service                static   disabled
-systemd-reboot.service                     static   disabled
-systemd-remount-fs.service                 static   disabled
-systemd-repart.service                     static   disabled
+systemd-quotacheck.service                 static
+systemd-random-seed.service                static
+systemd-reboot.service                     static
+systemd-remount-fs.service                 static
+systemd-repart.service                     static
 systemd-resolved.service                   disabled disabled
-systemd-rfkill.service                     static   disabled
-systemd-suspend-then-hibernate.service     static   disabled
-systemd-suspend.service                    static   disabled
-systemd-sysctl.service                     static   disabled
-systemd-sysusers.service                   static   disabled
+systemd-rfkill.service                     static
+systemd-suspend-then-hibernate.service     static
+systemd-suspend.service                    static
+systemd-sysctl.service                     static
+systemd-sysusers.service                   static
 systemd-time-wait-sync.service             disabled disabled
-systemd-timedated.service                  static   disabled
+systemd-timedated.service                  static
 systemd-timesyncd.service                  disabled disabled
-systemd-tmpfiles-clean.service             static   disabled
-systemd-tmpfiles-setup-dev.service         static   disabled
-systemd-tmpfiles-setup.service             static   disabled
-systemd-udev-settle.service                static   disabled
-systemd-udev-trigger.service               static   disabled
-systemd-udevd.service                      static   disabled
-systemd-update-done.service                static   disabled
-systemd-update-utmp-runlevel.service       static   disabled
-systemd-update-utmp.service                static   disabled
-systemd-user-sessions.service              static   disabled
-systemd-userdbd.service                    static   disabled
-systemd-vconsole-setup.service             static   disabled
-systemd-volatile-root.service              static   disabled
-teamd@.service                             static   disabled
+systemd-tmpfiles-clean.service             static
+systemd-tmpfiles-setup-dev.service         static
+systemd-tmpfiles-setup.service             static
+systemd-udev-settle.service                static
+systemd-udev-trigger.service               static
+systemd-udevd.service                      static
+systemd-update-done.service                static
+systemd-update-utmp-runlevel.service       static
+systemd-update-utmp.service                static
+systemd-user-sessions.service              static
+systemd-userdbd.service                    static
+systemd-vconsole-setup.service             static
+systemd-volatile-root.service              static
+teamd@.service                             static
 udisks2.service                            enabled  enabled
-user-runtime-dir@.service                  static   disabled
-user@.service                              static   disabled
+user-runtime-dir@.service                  static
+user@.service                              static
 winbind.service                            disabled disabled
 zram-swap.service                          enabled  disabled
-zram.service                               static   disabled
-system-cockpithttps.slice                  static   disabled
-system-systemd\x2dcryptsetup.slice         static   disabled
-user.slice                                 static   disabled
-cockpit-wsinstance-http-redirect.socket    static   disabled
-cockpit-wsinstance-http.socket             static   disabled
-cockpit-wsinstance-https-factory.socket    static   disabled
-cockpit-wsinstance-https@.socket           static   disabled
+zram.service                               static
+system-cockpithttps.slice                  static
+system-systemd\x2dcryptsetup.slice         static
+user.slice                                 static
+cockpit-wsinstance-http-redirect.socket    static
+cockpit-wsinstance-http.socket             static
+cockpit-wsinstance-https-factory.socket    static
+cockpit-wsinstance-https@.socket           static
 cockpit.socket                             enabled  enabled
 dbus.socket                                enabled  enabled
 dm-event.socket                            enabled  enabled
@@ -280,95 +280,95 @@
 sssd-pam.socket                            disabled disabled
 sssd-ssh.socket                            disabled disabled
 sssd-sudo.socket                           disabled disabled
-syslog.socket                              static   disabled
-systemd-coredump.socket                    static   disabled
-systemd-initctl.socket                     static   disabled
-systemd-journald-audit.socket              static   disabled
-systemd-journald-dev-log.socket            static   disabled
-systemd-journald-varlink@.socket           static   disabled
-systemd-journald.socket                    static   disabled
-systemd-journald@.socket                   static   disabled
+syslog.socket                              static
+systemd-coredump.socket                    static
+systemd-initctl.socket                     static
+systemd-journald-audit.socket              static
+systemd-journald-dev-log.socket            static
+systemd-journald-varlink@.socket           static
+systemd-journald.socket                    static
+systemd-journald@.socket                   static
 systemd-networkd.socket                    disabled disabled
-systemd-rfkill.socket                      static   disabled
-systemd-udevd-control.socket               static   disabled
-systemd-udevd-kernel.socket                static   disabled
-systemd-userdbd.socket                     static   disabled
-anaconda.target                            static   disabled
-basic.target                               static   disabled
-blockdev@.target                           static   disabled
-bluetooth.target                           static   enabled
-boot-complete.target                       static   disabled
-cryptsetup-pre.target                      static   disabled
-cryptsetup.target                          static   disabled
-ctrl-alt-del.target                        enabled  disabled
-default.target                             indirect disabled
-emergency.target                           static   disabled
+systemd-rfkill.socket                      static
+systemd-udevd-control.socket               static
+systemd-udevd-kernel.socket                static
+systemd-userdbd.socket                     static
+anaconda.target                            static
+basic.target                               static
+blockdev@.target                           static
+bluetooth.target                           static
+boot-complete.target                       static
+cryptsetup-pre.target                      static
+cryptsetup.target                          static
+ctrl-alt-del.target                        alias
+default.target                             alias
+emergency.target                           static
 exit.target                                disabled disabled
-final.target                               static   disabled
-getty-pre.target                           static   disabled
-getty.target                               static   disabled
-graphical.target                           static   disabled
+final.target                               static
+getty-pre.target                           static
+getty.target                               static
+graphical.target                           static
 halt.target                                disabled disabled
-hibernate.target                           static   disabled
-hybrid-sleep.target                        static   disabled
-initrd-fs.target                           static   disabled
-initrd-root-device.target                  static   disabled
-initrd-root-fs.target                      static   disabled
-initrd-switch-root.target                  static   disabled
-initrd.target                              static   disabled
+hibernate.target                           static
+hybrid-sleep.target                        static
+initrd-fs.target                           static
+initrd-root-device.target                  static
+initrd-root-fs.target                      static
+initrd-switch-root.target                  static
+initrd.target                              static
 kexec.target                               disabled disabled
-local-fs-pre.target                        static   disabled
-local-fs.target                            static   disabled
+local-fs-pre.target                        static
+local-fs.target                            static
 multi-user.target                          indirect disabled
-network-online.target                      static   disabled
-network-pre.target                         static   disabled
-network.target                             static   disabled
+network-online.target                      static
+network-pre.target                         static
+network.target                             static
 nfs-client.target                          enabled  disabled
-nss-lookup.target                          static   disabled
-nss-user-lookup.target                     static   disabled
-paths.target                               static   disabled
+nss-lookup.target                          static
+nss-user-lookup.target                     static
+paths.target                               static
 poweroff.target                            disabled disabled
-printer.target                             static   disabled
+printer.target                             static
 reboot.target                              enabled  enabled
 remote-cryptsetup.target                   disabled enabled
-remote-fs-pre.target                       static   disabled
+remote-fs-pre.target                       static
 remote-fs.target                           enabled  enabled
-rescue.target                              static   disabled
-rpc_pipefs.target                          static   disabled
-rpcbind.target                             static   disabled
-runlevel0.target                           disabled disabled
-runlevel1.target                           static   disabled
-runlevel2.target                           indirect disabled
-runlevel3.target                           indirect disabled
-runlevel4.target                           indirect disabled
-runlevel5.target                           static   disabled
-runlevel6.target                           enabled  disabled
-selinux-autorelabel.target                 static   disabled
-shutdown.target                            static   disabled
-sigpwr.target                              static   disabled
-sleep.target                               static   disabled
-slices.target                              static   disabled
-smartcard.target                           static   disabled
-sockets.target                             static   disabled
-sound.target                               static   disabled
-sshd-keygen.target                         static   disabled
-suspend-then-hibernate.target              static   disabled
-suspend.target                             static   disabled
-swap.target                                static   disabled
-sysinit.target                             static   disabled
-system-update-pre.target                   static   disabled
-system-update.target                       static   disabled
-time-set.target                            static   disabled
-time-sync.target                           static   disabled
-timers.target                              static   disabled
-umount.target                              static   disabled
+rescue.target                              static
+rpc_pipefs.target                          static
+rpcbind.target                             static
+runlevel0.target                           alias
+runlevel1.target                           alias
+runlevel2.target                           alias
+runlevel3.target                           alias
+runlevel4.target                           alias
+runlevel5.target                           alias
+runlevel6.target                           alias
+selinux-autorelabel.target                 static
+shutdown.target                            static
+sigpwr.target                              static
+sleep.target                               static
+slices.target                              static
+smartcard.target                           static
+sockets.target                             static
+sound.target                               static
+sshd-keygen.target                         static
+suspend-then-hibernate.target              static
+suspend.target                             static
+swap.target                                static
+sysinit.target                             static
+system-update-pre.target                   static
+system-update.target                       static
+time-set.target                            static
+time-sync.target                           static
+timers.target                              static
+umount.target                              static
 chrony-dnssrv@.timer                       disabled disabled
 dnf-makecache.timer                        enabled  enabled
 fstrim.timer                               enabled  enabled
 logrotate.timer                            enabled  enabled
-mdadm-last-resort@.timer                   static   disabled
+mdadm-last-resort@.timer                   static
 mlocate-updatedb.timer                     enabled  enabled
 raid-check.timer                           disabled disabled
-systemd-tmpfiles-clean.timer               static   disabled
+systemd-tmpfiles-clean.timer               static

 371 unit files listed.

In particular, this allows a meaningful comparison to be made:

$ ~/src/systemd/build/systemctl --root=/tmp/root2 list-unit-files|rg 'enabled.*disabled|disabled.*enabled'
ostree-finalize-staged.path                disabled enabled
initial-setup.service                      enabled  disabled
iscsi.service                              enabled  disabled
nfs-convert.service                        enabled  disabled
systemd-pstore.service                     disabled enabled
zram-swap.service                          enabled  disabled
iscsid.socket                              enabled  disabled
iscsiuio.socket                            enabled  disabled
multipathd.socket                          enabled  disabled
nfs-client.target                          enabled  disabled
remote-cryptsetup.target                   disabled enabled

(It turns out that most of the services on this list that are enabled without a
corresponding preset are against rpm packaging and do direct 'systemctl enable'
calls in %post, instead of going through presets as they are supposed to.)

systemctl: also skip preset status in status verb
2020-05-05 22:03:53 +02:00
Zbigniew Jędrzejewski-Szmek
15d7ab87c4 systemctl: add new enablement state "alias"
For units which are aliases of other units, reporting preset status as
"enabled" is rather misleading. For example, dbus.service is an alias of
dbus-broker.service. In list-unit-files we'd show both as "enabled".  In
particular, systemctl preset ignores aliases, so showing any preset status at
all is always going to be misleading. Let's introduce a new state "alias" and
use that for all aliases.

I was trying to avoid adding a new state, to keep compatibility with previous
behaviour, but for alias unit files it simply doesn't seem very useful to show
any of the existing states. It seems that the clearly showing that those are
aliases for other units will be easiest to understand for users.
2020-05-05 21:50:38 +02:00
Zbigniew Jędrzejewski-Szmek
9c894b8579 shared/install: rename variable for clarity 2020-05-05 21:50:38 +02:00
Zbigniew Jędrzejewski-Szmek
bce84e10f8 shared/install: print name of offending file in error
"Unit type slice cannot be templated."
↓
"/etc/systemd/system.control/user@.slice: unit type slice cannot be templated."
2020-05-05 21:50:38 +02:00
Zbigniew Jędrzejewski-Szmek
babccf14ce shared/install: indent tables 2020-05-05 21:50:38 +02:00
Zbigniew Jędrzejewski-Szmek
8f7b256665 shared/install: optionally cache the preset list
When doing list-unit-files with --root, we would re-read the preset
list for every unit. This uses a cache to only do it once. The time
for list-unit-files goes down by about ~30%.

unit_file_query_preset() is also called from src/core/. This patch does not
touch that path, since the saving there are smaller, since preset status is
only read on demand over dbus, and caching would be more complicated.
2020-05-05 21:50:31 +02:00
Zbigniew Jędrzejewski-Szmek
c39b7821f6 systemctl: fix --root support in querying presets
We would always look on the host, ignoring --root.
2020-05-05 18:05:32 +02:00
Zbigniew Jędrzejewski-Szmek
4cb1015e6b systemctl: refuse online-only ops with --root
It is super confusing when a command does not support --root, and is called
with it specified, and returns some bogus results. Let's just catch this
early and refuse.
2020-05-05 18:05:23 +02:00
Zbigniew Jędrzejewski-Szmek
9321e23c40 shared/verbs: split out helper to find verbs
It will be used later, but I think it makes the code clearer anyway.

Also change the message about ignoring to include the name for default
verbs.
2020-05-05 18:04:55 +02:00
Zbigniew Jędrzejewski-Szmek
d8b065e056 shared/verbs: add a modicum of documentation 2020-05-05 18:04:44 +02:00
Zbigniew Jędrzejewski-Szmek
ae98f726ff systemctl: mark log-level,log-target,service-watchdogs as online-only
They were added in 6ab863190dee5ab631795ef547fcc7314ddccd40 and
38fcb7f766c84736425e86854b8a4468c126dafa. I don't see a good reason to
exclude them from the online-only check.
2020-05-05 18:04:36 +02:00
Zbigniew Jędrzejewski-Szmek
77102db288 systemctl: fix hint when 'systemctl help' is given
Not all verbs require unit names, but that is beside the point. We need a verb
here, and help is not a valid verb.
2020-05-05 18:04:28 +02:00
Zbigniew Jędrzejewski-Szmek
b8239b9c50 shared/unit-file: fix resolution of absoulute symlinks with --root
$ systemctl --no-pager --root /tmp/root2/ cat ctrl-alt-del.target
Failed to resolve symlink /tmp/root2/etc/systemd/system/ctrl-alt-del.target pointing to /usr/lib/systemd/system/reboot.target, ignoring: Channel number out of range
...
2020-04-30 12:02:44 +02:00
Zbigniew Jędrzejewski-Szmek
26b8190841 man: mention that ProtectSystem= also takes care of /efi 2020-04-30 09:54:00 +02:00
21 changed files with 672 additions and 376 deletions

View File

@ -113,7 +113,7 @@ Here's the step-by-step guide:
home directory temporarily and copy the data in.
```
homectl with foobar -- rsync -aHAXv --delete-during /home/foobar.saved/ .
homectl with foobar -- rsync -aHAXv --remove-source-files /home/foobar.saved/ .
```
This mounts the home directory of the user, and then runs the specified
@ -121,7 +121,7 @@ Here's the step-by-step guide:
new. The new home directory is the working directory of the invoked `rsync`
process. We are invoking this command as root, hence the `rsync` runs as
root too. When the `rsync` command completes the home directory is
automatically unmounted again. Since we used `--delete-during` all files
automatically unmounted again. Since we used `--remove-source-files` all files
copied are removed from the old home directory as the copy progresses. After
the command completes the old home directory should be empty. Let's remove
it hence:

View File

@ -132,6 +132,25 @@
<para>
<constant>SD_BUS_VTABLE_END</constant>
</para>
<para>
<constant>SD_BUS_METHOD_WITH_ARGS_OFFSET(
<replaceable>member</replaceable>,
<replaceable>args</replaceable>,
<replaceable>result</replaceable>,
<replaceable>handler</replaceable>,
<replaceable>offset</replaceable>,
<replaceable>flags</replaceable>)
</constant>
</para>
<para>
<constant>SD_BUS_METHOD_WITH_ARGS(
<replaceable>member</replaceable>,
<replaceable>args</replaceable>,
<replaceable>result</replaceable>,
<replaceable>handler</replaceable>,
<replaceable>flags</replaceable>)
</constant>
</para>
<para>
<constant>SD_BUS_METHOD_WITH_NAMES_OFFSET(
<replaceable>member</replaceable>,
@ -174,6 +193,13 @@
<replaceable>flags</replaceable>)
</constant>
</para>
<para>
<constant>SD_BUS_SIGNAL_WITH_ARGS(
<replaceable>member</replaceable>,
<replaceable>args</replaceable>,
<replaceable>flags</replaceable>)
</constant>
</para>
<para>
<constant>SD_BUS_SIGNAL_WITH_NAMES(
<replaceable>member</replaceable>,
@ -210,6 +236,10 @@
</para>
<para>
<constant>SD_BUS_PARAM(<replaceable>name</replaceable>)</constant>
<constant>SD_BUS_ARGS(<replaceable>...</replaceable>)</constant>
<constant>SD_BUS_RESULT(<replaceable>...</replaceable>)</constant>
<constant>SD_BUS_NO_ARGS</constant>
<constant>SD_BUS_NO_RESULT</constant>
</para>
</funcsynopsis>
</refsynopsisdiv>
@ -315,6 +345,40 @@
<listitem><para>Those must always be the first and last element.</para></listitem>
</varlistentry>
<varlistentry>
<term><constant>SD_BUS_METHOD_WITH_ARGS_OFFSET()</constant></term>
<term><constant>SD_BUS_METHOD_WITH_ARGS()</constant></term>
<listitem><para>Declare a D-Bus method with the name <replaceable>member</replaceable>,
arguments <replaceable>args</replaceable> and result <replaceable>result</replaceable>.
<replaceable>args</replaceable> expects a sequence of argument type/name pairs wrapped in the
<constant>SD_BUS_ARGS()</constant> macro. The elements at even indices in this list describe the
types of the method's arguments. The method's parameter signature is the concatenation of all the
string literals at even indices in <replaceable>args</replaceable>. If a method has no parameters,
pass <constant>SD_BUS_NO_ARGS</constant> to <replaceable>args</replaceable>. The elements at uneven
indices describe the names of the method's arguments. <replaceable>result</replaceable> expects a
sequence of type/name pairs wrapped in the <constant>SD_BUS_RESULT()</constant> macro in the same
format as <constant>SD_BUS_ARGS()</constant>. The method's result signature is the concatenation of
all the string literals at even indices in <replaceable>result</replaceable>. If a method has no
result, pass <constant>SD_BUS_NO_RESULT</constant> to <replaceable>result</replaceable>. Note that
argument types are expected to be quoted string literals and argument names are expected to be
unquoted string literals. See below for a complete example.</para>
<para>The handler function <replaceable>handler</replaceable> must be of type
<function>sd_bus_message_handler_t</function>. It will be called to handle the incoming messages
that call this method. It receives a pointer that is the <replaceable>userdata</replaceable>
parameter passed to the registration function offset by <replaceable>offset</replaceable> bytes.
This may be used to pass pointers to different fields in the same data structure to different
methods in the same vtable. To send a reply from <parameter>handler</parameter>, call
<citerefentry><refentrytitle>sd_bus_reply_method_return</refentrytitle><manvolnum>3</manvolnum></citerefentry>
with the message the callback was invoked with. Parameter <replaceable>flags</replaceable> is a
combination of flags, see below.</para>
<constant>SD_BUS_METHOD_WITH_ARGS()</constant> is a shorthand for calling
<constant>SD_BUS_METHOD_WITH_ARGS_OFFSET()</constant> with an offset of zero.
</listitem>
</varlistentry>
<varlistentry>
<term><constant>SD_BUS_METHOD_WITH_NAMES_OFFSET()</constant></term>
<term><constant>SD_BUS_METHOD_WITH_NAMES()</constant></term>
@ -325,27 +389,37 @@
parameter signature <replaceable>signature</replaceable>, result signature
<replaceable>result</replaceable>. Parameters <replaceable>in_names</replaceable> and
<replaceable>out_names</replaceable> specify the argument names of the input and output
arguments in the function signature. The handler function
<replaceable>handler</replaceable> must be of type
<function>sd_bus_message_handler_t</function>. It will be called to handle the incoming
messages that call this method. It receives a pointer that is the
<replaceable>userdata</replaceable> parameter passed to the registration function offset
by <replaceable>offset</replaceable> bytes. This may be used to pass pointers to different
fields in the same data structure to different methods in the same vtable. To send a reply
from <parameter>handler</parameter>, call
<citerefentry><refentrytitle>sd_bus_reply_method_return</refentrytitle><manvolnum>3</manvolnum></citerefentry>
with the message the callback was invoked with. <replaceable>in_names</replaceable> and
arguments in the function signature. <replaceable>in_names</replaceable> and
<replaceable>out_names</replaceable> should be created using the
<constant>SD_BUS_PARAM()</constant> macro, see below. Parameter
<replaceable>flags</replaceable> is a combination of flags, see below.</para>
<constant>SD_BUS_PARAM()</constant> macro, see below. In all other regards, this macro behaves
exactly the same as <constant>SD_BUS_METHOD_WITH_ARGS_OFFSET()</constant>.</para>
<para><constant>SD_BUS_METHOD_WITH_NAMES()</constant>,
<constant>SD_BUS_METHOD_WITH_OFFSET()</constant>, and <constant>SD_BUS_METHOD()</constant>
are variants which specify zero offset (<replaceable>userdata</replaceable> parameter is
passed with no change), leave the names unset (i.e. no parameter names), or both.</para>
<para>Prefer using <constant>SD_BUS_METHOD_WITH_ARGS_OFFSET()</constant> and
<constant>SD_BUS_METHOD_WITH_ARGS()</constant> over these macros as they allow specifying argument
types and names next to each other which is less error-prone than first specifying all argument
types followed by specifying all argument names.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><constant>SD_BUS_SIGNAL_WITH_ARGS()</constant></term>
<listitem><para>>Declare a D-Bus signal with the name <replaceable>member</replaceable> and
arguments <replaceable>args</replaceable>. <replaceable>args</replaceable> expects a sequence of
argument type/name pairs wrapped in the <constant>SD_BUS_ARGS()</constant> macro. The elements at
even indices in this list describe the types of the signal's arguments. The signal's parameter
signature is the concatenation of all the string literals at even indices in
<replaceable>args</replaceable>. If a signal has no parameters, pass
<constant>SD_BUS_NO_ARGS</constant> to <replaceable>args</replaceable>. The elements at uneven
indices describe the names of the signal's arguments. Parameter <replaceable>flags</replaceable> is
a combination of flags. See below for a complete example.</para></listitem>
</varlistentry>
<varlistentry>
<term><constant>SD_BUS_SIGNAL_WITH_NAMES()</constant></term>
<term><constant>SD_BUS_SIGNAL()</constant></term>
@ -357,8 +431,13 @@
Parameter <replaceable>flags</replaceable> is a combination of flags, see below.
</para>
<para>Equivalent to <constant>SD_BUS_SIGNAL_WITH_NAMES()</constant> with the
<replaceable>names</replaceable> parameter unset (i.e. no parameter names).</para>
<para><constant>SD_BUS_SIGNAL()</constant> is equivalent to
<constant>SD_BUS_SIGNAL_WITH_NAMES()</constant> with the <replaceable>names</replaceable> parameter
unset (i.e. no parameter names).</para>
<para>Prefer using <constant>SD_BUS_SIGNAL_WITH_ARGS()</constant> over these macros as it allows
specifying argument types and names next to each other which is less error-prone than first
specifying all argument types followed by specifying all argument names.</para>
</listitem>
</varlistentry>

View File

@ -753,6 +753,11 @@ Jan 12 10:46:45 example.com bluetoothd[8900]: gatt-time-server: Input/output err
<row>
<entry><literal>linked-runtime</literal></entry>
</row>
<row>
<entry><literal>alias</literal></entry>
<entry>The name is an alias (symlink to another unit file).</entry>
<entry>0</entry>
</row>
<row>
<entry><literal>masked</literal></entry>
<entry morerows='1'>Completely disabled, so that any start operation on it fails (permanently in <filename>/etc/systemd/system/</filename> or transiently in <filename>/run/systemd/systemd/</filename>).</entry>

View File

@ -67,6 +67,13 @@
<listitem><para>Sets the maximum number of simultaneous connections, defaults to 256.
If the limit of concurrent connections is reached further connections will be refused.</para></listitem>
</varlistentry>
<varlistentry>
<term><option>--exit-idle-time=</option></term>
<listitem><para>Sets the time before exiting when there are no connections, defaults to
<constant>infinity</constant>. Takes a unit-less value in seconds, or a time span value such
as <literal>5min 20s</literal>.</para></listitem>
</varlistentry>
</variablelist>
</refsect1>
<refsect1>
@ -115,6 +122,9 @@ server {
<programlisting><![CDATA[# systemctl enable --now proxy-to-nginx.socket
$ curl http://localhost:80/]]></programlisting>
</example>
<para>If <filename>nginx.service</filename> has <varname>StopWhenUnneeded=</varname> set, then
passing <option>--exit-idle-time=</option> to <command>systemd-socket-proxyd</command> allows
both services to stop during idle periods.</para>
</refsect2>
<refsect2>
<title>Namespace Example</title>

View File

@ -891,10 +891,11 @@ CapabilityBoundingSet=~CAP_B CAP_C</programlisting>
<term><varname>ProtectSystem=</varname></term>
<listitem><para>Takes a boolean argument or the special values <literal>full</literal> or
<literal>strict</literal>. If true, mounts the <filename>/usr</filename> and <filename>/boot</filename>
directories read-only for processes invoked by this unit. If set to <literal>full</literal>, the
<filename>/etc</filename> directory is mounted read-only, too. If set to <literal>strict</literal> the entire
file system hierarchy is mounted read-only, except for the API file system subtrees <filename>/dev</filename>,
<literal>strict</literal>. If true, mounts the <filename>/usr</filename> and the boot loader
directories (<filename>/boot</filename> and <filename>/efi</filename>) read-only for processes
invoked by this unit. If set to <literal>full</literal>, the <filename>/etc</filename> directory is
mounted read-only, too. If set to <literal>strict</literal> the entire file system hierarchy is
mounted read-only, except for the API file system subtrees <filename>/dev</filename>,
<filename>/proc</filename> and <filename>/sys</filename> (protect these directories using
<varname>PrivateDevices=</varname>, <varname>ProtectKernelTunables=</varname>,
<varname>ProtectControlGroups=</varname>). This setting ensures that any modification of the vendor-supplied

View File

@ -27,6 +27,30 @@ static const sd_bus_vtable vtable[] = {
"s", SD_BUS_PARAM(returnstring),
method, offsetof(object, number),
SD_BUS_VTABLE_DEPRECATED),
SD_BUS_METHOD_WITH_ARGS_OFFSET(
"Method3",
SD_BUS_ARGS("s", string, "o", path),
SD_BUS_RESULT("s", returnstring),
method, offsetof(object, number),
SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD_WITH_ARGS(
"Method4",
SD_BUS_NO_ARGS,
SD_BUS_NO_RESULT,
method,
SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_SIGNAL(
"Signal1",
"so",
0),
SD_BUS_SIGNAL_WITH_NAMES(
"Signal2",
"so", SD_BUS_PARAM(string) SD_BUS_PARAM(path),
0),
SD_BUS_SIGNAL_WITH_ARGS(
"Signal3",
SD_BUS_ARGS("s", string, "o", path),
0),
SD_BUS_WRITABLE_PROPERTY(
"AutomaticStringProperty", "s", NULL, NULL,
offsetof(object, name),

View File

@ -377,9 +377,6 @@ possible_cc_flags = [
'-Wno-error=#warnings', # clang
'-Wno-string-plus-int', # clang
# work-around for gcc 7.1 turning this on on its own.
'-Wno-error=nonnull',
# Disable -Wmaybe-uninitialized, since it's noisy on gcc 8 with
# optimizations enabled, producing essentially false positives.
'-Wno-maybe-uninitialized',

View File

@ -4316,7 +4316,8 @@ int unit_get_unit_file_preset(Unit *u) {
u->unit_file_preset = unit_file_query_preset(
u->manager->unit_file_scope,
NULL,
basename(u->fragment_path));
basename(u->fragment_path),
NULL);
return u->unit_file_preset;
}

View File

@ -1855,162 +1855,117 @@ static const sd_bus_vtable resolve_vtable[] = {
SD_BUS_PROPERTY("DNSSECNegativeTrustAnchors", "as", bus_property_get_ntas, 0, 0),
SD_BUS_PROPERTY("DNSStubListener", "s", bus_property_get_dns_stub_listener_mode, offsetof(Manager, dns_stub_listener_mode), 0),
SD_BUS_METHOD_WITH_NAMES("ResolveHostname",
"isit",
SD_BUS_PARAM(ifindex)
SD_BUS_PARAM(name)
SD_BUS_PARAM(family)
SD_BUS_PARAM(flags),
"a(iiay)st",
SD_BUS_PARAM(addresses)
SD_BUS_PARAM(canonical)
SD_BUS_PARAM(flags),
bus_method_resolve_hostname,
SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD_WITH_NAMES("ResolveAddress",
"iiayt",
SD_BUS_PARAM(ifindex)
SD_BUS_PARAM(family)
SD_BUS_PARAM(address)
SD_BUS_PARAM(flags),
"a(is)t",
SD_BUS_PARAM(names)
SD_BUS_PARAM(flags),
bus_method_resolve_address,
SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD_WITH_NAMES("ResolveRecord",
"isqqt",
SD_BUS_PARAM(ifindex)
SD_BUS_PARAM(name)
SD_BUS_PARAM(class)
SD_BUS_PARAM(type)
SD_BUS_PARAM(flags),
"a(iqqay)t",
SD_BUS_PARAM(records)
SD_BUS_PARAM(flags),
bus_method_resolve_record,
SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD_WITH_NAMES("ResolveService",
"isssit",
SD_BUS_PARAM(ifindex)
SD_BUS_PARAM(name)
SD_BUS_PARAM(type)
SD_BUS_PARAM(domain)
SD_BUS_PARAM(family)
SD_BUS_PARAM(flags),
"a(qqqsa(iiay)s)aayssst",
SD_BUS_PARAM(srv_data)
SD_BUS_PARAM(txt_data)
SD_BUS_PARAM(canonical_name)
SD_BUS_PARAM(canonical_type)
SD_BUS_PARAM(canonical_domain)
SD_BUS_PARAM(flags),
bus_method_resolve_service,
SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD_WITH_NAMES("GetLink",
"i",
SD_BUS_PARAM(ifindex),
"o",
SD_BUS_PARAM(path),
bus_method_get_link,
SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD_WITH_NAMES("SetLinkDNS",
"ia(iay)",
SD_BUS_PARAM(ifindex)
SD_BUS_PARAM(addresses),
NULL,,
bus_method_set_link_dns_servers,
SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD_WITH_NAMES("SetLinkDomains",
"ia(sb)",
SD_BUS_PARAM(ifindex)
SD_BUS_PARAM(domains),
NULL,,
bus_method_set_link_domains,
SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD_WITH_NAMES("SetLinkDefaultRoute",
"ib",
SD_BUS_PARAM(ifindex)
SD_BUS_PARAM(enable),
NULL,,
bus_method_set_link_default_route,
SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD_WITH_NAMES("SetLinkLLMNR",
"is",
SD_BUS_PARAM(ifindex)
SD_BUS_PARAM(mode),
NULL,,
bus_method_set_link_llmnr,
SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD_WITH_NAMES("SetLinkMulticastDNS",
"is",
SD_BUS_PARAM(ifindex)
SD_BUS_PARAM(mode),
NULL,,
bus_method_set_link_mdns,
SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD_WITH_NAMES("SetLinkDNSOverTLS",
"is",
SD_BUS_PARAM(ifindex)
SD_BUS_PARAM(mode),
NULL,,
bus_method_set_link_dns_over_tls,
SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD_WITH_NAMES("SetLinkDNSSEC",
"is",
SD_BUS_PARAM(ifindex)
SD_BUS_PARAM(mode),
NULL,,
bus_method_set_link_dnssec,
SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD_WITH_NAMES("SetLinkDNSSECNegativeTrustAnchors",
"ias",
SD_BUS_PARAM(ifindex)
SD_BUS_PARAM(names),
NULL,,
bus_method_set_link_dnssec_negative_trust_anchors,
SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD_WITH_NAMES("RevertLink",
"i",
SD_BUS_PARAM(ifindex),
NULL,,
bus_method_revert_link,
SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD_WITH_NAMES("RegisterService",
"sssqqqaa{say}",
SD_BUS_PARAM(name)
SD_BUS_PARAM(name_template)
SD_BUS_PARAM(type)
SD_BUS_PARAM(service_port)
SD_BUS_PARAM(service_priority)
SD_BUS_PARAM(serwise_weight)
SD_BUS_PARAM(txt_datas),
"o",
SD_BUS_PARAM(service_path),
bus_method_register_service,
SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD_WITH_NAMES("UnregisterService",
"o",
SD_BUS_PARAM(service_path),
NULL,,
bus_method_unregister_service,
SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("ResetStatistics",
NULL,
NULL,
bus_method_reset_statistics,
SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("FlushCaches",
NULL,
NULL,
bus_method_flush_caches,
SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("ResetServerFeatures",
NULL,
NULL,
bus_method_reset_server_features,
SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD_WITH_ARGS("ResolveHostname",
SD_BUS_ARGS("i", ifindex, "s", name, "i", family, "t", flags),
SD_BUS_RESULT("a(iiay)", addresses, "s", canonical, "t", flags),
bus_method_resolve_hostname,
SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD_WITH_ARGS("ResolveAddress",
SD_BUS_ARGS("i", ifindex, "i", family, "ay", address, "t", flags),
SD_BUS_RESULT("a(is)", names, "t", flags),
bus_method_resolve_address,
SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD_WITH_ARGS("ResolveRecord",
SD_BUS_ARGS("i", ifindex, "s", name, "q", class, "q", type, "t", flags),
SD_BUS_RESULT("a(iqqay)", records, "t", flags),
bus_method_resolve_record,
SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD_WITH_ARGS("ResolveService",
SD_BUS_ARGS("i", ifindex,
"s", name,
"s", type,
"s", domain,
"i", family,
"t", flags),
SD_BUS_RESULT("a(qqqsa(iiay)s)", srv_data,
"aay", txt_data,
"s", canonical_name,
"s", canonical_type,
"s", canonical_domain,
"t", flags),
bus_method_resolve_service,
SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD_WITH_ARGS("GetLink",
SD_BUS_ARGS("i", ifindex),
SD_BUS_RESULT("o", path),
bus_method_get_link,
SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD_WITH_ARGS("SetLinkDNS",
SD_BUS_ARGS("i", ifindex, "a(iay)", addresses),
SD_BUS_NO_RESULT,
bus_method_set_link_dns_servers,
SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD_WITH_ARGS("SetLinkDomains",
SD_BUS_ARGS("i", ifindex, "a(sb)", domains),
SD_BUS_NO_RESULT,
bus_method_set_link_domains,
SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD_WITH_ARGS("SetLinkDefaultRoute",
SD_BUS_ARGS("i", ifindex, "b", enable),
SD_BUS_NO_RESULT,
bus_method_set_link_default_route,
SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD_WITH_ARGS("SetLinkLLMNR",
SD_BUS_ARGS("i", ifindex, "s", mode),
SD_BUS_NO_RESULT,
bus_method_set_link_llmnr,
SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD_WITH_ARGS("SetLinkMulticastDNS",
SD_BUS_ARGS("i", ifindex, "s", mode),
SD_BUS_NO_RESULT,
bus_method_set_link_mdns,
SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD_WITH_ARGS("SetLinkDNSOverTLS",
SD_BUS_ARGS("i", ifindex, "s", mode),
SD_BUS_NO_RESULT,
bus_method_set_link_dns_over_tls,
SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD_WITH_ARGS("SetLinkDNSSEC",
SD_BUS_ARGS("i", ifindex, "s", mode),
SD_BUS_NO_RESULT,
bus_method_set_link_dnssec,
SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD_WITH_ARGS("SetLinkDNSSECNegativeTrustAnchors",
SD_BUS_ARGS("i", ifindex, "as", names),
SD_BUS_NO_RESULT,
bus_method_set_link_dnssec_negative_trust_anchors,
SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD_WITH_ARGS("RevertLink",
SD_BUS_ARGS("i", ifindex),
SD_BUS_NO_RESULT,
bus_method_revert_link,
SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD_WITH_ARGS("RegisterService",
SD_BUS_ARGS("s", name,
"s", name_template,
"s", type,
"q", service_port,
"q", service_priority,
"q", service_weight,
"a{say}", txt_datas),
SD_BUS_RESULT("o", service_path),
bus_method_register_service,
SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD_WITH_ARGS("UnregisterService",
SD_BUS_ARGS("o", service_path),
SD_BUS_NO_RESULT,
bus_method_unregister_service,
SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD_WITH_ARGS("ResetStatistics",
SD_BUS_NO_ARGS,
SD_BUS_NO_RESULT,
bus_method_reset_statistics,
SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD_WITH_ARGS("FlushCaches",
SD_BUS_NO_ARGS,
SD_BUS_NO_RESULT,
bus_method_flush_caches,
SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD_WITH_ARGS("ResetServerFeatures",
SD_BUS_NO_ARGS,
SD_BUS_NO_RESULT,
bus_method_reset_server_features,
SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_VTABLE_END,
};

View File

@ -697,56 +697,51 @@ const sd_bus_vtable link_vtable[] = {
SD_BUS_PROPERTY("DNSSECNegativeTrustAnchors", "as", property_get_ntas, 0, 0),
SD_BUS_PROPERTY("DNSSECSupported", "b", property_get_dnssec_supported, 0, 0),
SD_BUS_METHOD_WITH_NAMES("SetDNS",
"a(iay)",
SD_BUS_PARAM(addresses),
NULL,,
bus_link_method_set_dns_servers,
SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD_WITH_NAMES("SetDomains",
"a(sb)",
SD_BUS_PARAM(domains),
NULL,,
bus_link_method_set_domains,
SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD_WITH_NAMES("SetDefaultRoute",
"b",
SD_BUS_PARAM(enable),
NULL,,
bus_link_method_set_default_route,
SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD_WITH_NAMES("SetLLMNR",
"s",
SD_BUS_PARAM(mode),
NULL,,
bus_link_method_set_llmnr,
SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD_WITH_NAMES("SetMulticastDNS",
"s",
SD_BUS_PARAM(mode),
NULL,,
bus_link_method_set_mdns,
SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD_WITH_NAMES("SetDNSOverTLS",
"s",
SD_BUS_PARAM(mode),
NULL,,
bus_link_method_set_dns_over_tls,
SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD_WITH_NAMES("SetDNSSEC",
"s",
SD_BUS_PARAM(mode),
NULL,,
bus_link_method_set_dnssec,
SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD_WITH_NAMES("SetDNSSECNegativeTrustAnchors",
"as",
SD_BUS_PARAM(names),
NULL,,
bus_link_method_set_dnssec_negative_trust_anchors,
SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("Revert", NULL, NULL, bus_link_method_revert, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD_WITH_ARGS("SetDNS",
SD_BUS_ARGS("a(iay)", addresses),
SD_BUS_NO_RESULT,
bus_link_method_set_dns_servers,
SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD_WITH_ARGS("SetDomains",
SD_BUS_ARGS("a(sb)", domains),
SD_BUS_NO_RESULT,
bus_link_method_set_domains,
SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD_WITH_ARGS("SetDefaultRoute",
SD_BUS_ARGS("b", enable),
SD_BUS_NO_RESULT,
bus_link_method_set_default_route,
SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD_WITH_ARGS("SetLLMNR",
SD_BUS_ARGS("s", mode),
SD_BUS_NO_RESULT,
bus_link_method_set_llmnr,
SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD_WITH_ARGS("SetMulticastDNS",
SD_BUS_ARGS("s", mode),
SD_BUS_NO_RESULT,
bus_link_method_set_mdns,
SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD_WITH_ARGS("SetDNSOverTLS",
SD_BUS_ARGS("s", mode),
SD_BUS_NO_RESULT,
bus_link_method_set_dns_over_tls,
SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD_WITH_ARGS("SetDNSSEC",
SD_BUS_ARGS("s", mode),
SD_BUS_NO_RESULT,
bus_link_method_set_dnssec,
SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD_WITH_ARGS("SetDNSSECNegativeTrustAnchors",
SD_BUS_ARGS("as", names),
SD_BUS_NO_RESULT,
bus_link_method_set_dnssec_negative_trust_anchors,
SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD_WITH_ARGS("Revert",
SD_BUS_NO_ARGS,
SD_BUS_NO_RESULT,
bus_link_method_revert,
SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_VTABLE_END
};

View File

@ -55,16 +55,11 @@ typedef enum {
PRESET_DISABLE,
} PresetAction;
typedef struct {
struct UnitFilePresetRule {
char *pattern;
PresetAction action;
char **instances;
} PresetRule;
typedef struct {
PresetRule *rules;
size_t n_rules;
} Presets;
};
static bool unit_file_install_info_has_rules(const UnitFileInstallInfo *i) {
assert(i);
@ -80,7 +75,7 @@ static bool unit_file_install_info_has_also(const UnitFileInstallInfo *i) {
return !strv_isempty(i->also);
}
static void presets_freep(Presets *p) {
void unit_file_presets_freep(UnitFilePresets *p) {
size_t i;
if (!p)
@ -1231,7 +1226,7 @@ static int unit_file_load(
return -EINVAL;
if (unit_name_is_valid(info->name, UNIT_NAME_TEMPLATE|UNIT_NAME_INSTANCE) && !unit_type_may_template(type))
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
"Unit type %s cannot be templated.", unit_type_to_string(type));
"%s: unit type %s cannot be templated, ignoring.", path, unit_type_to_string(type));
if (!(flags & SEARCH_LOAD)) {
r = lstat(path, &st);
@ -2772,6 +2767,12 @@ int unit_file_lookup_state(
break;
case UNIT_FILE_TYPE_REGULAR:
/* Check if the name we were querying is actually an alias */
if (!streq(name, basename(i->path)) && !unit_name_is_valid(i->name, UNIT_NAME_INSTANCE)) {
state = UNIT_FILE_ALIAS;
break;
}
r = path_is_generator(paths, i->path);
if (r < 0)
return r;
@ -2913,8 +2914,8 @@ static int presets_find_config(UnitFileScope scope, const char *root_dir, char *
return conf_files_list_strv(files, ".preset", root_dir, 0, dirs);
}
static int read_presets(UnitFileScope scope, const char *root_dir, Presets *presets) {
_cleanup_(presets_freep) Presets ps = {};
static int read_presets(UnitFileScope scope, const char *root_dir, UnitFilePresets *presets) {
_cleanup_(unit_file_presets_freep) UnitFilePresets ps = {};
size_t n_allocated = 0;
_cleanup_strv_free_ char **files = NULL;
char **p;
@ -2942,7 +2943,7 @@ static int read_presets(UnitFileScope scope, const char *root_dir, Presets *pres
for (;;) {
_cleanup_free_ char *line = NULL;
PresetRule rule = {};
UnitFilePresetRule rule = {};
const char *parameter;
char *l;
@ -2972,7 +2973,7 @@ static int read_presets(UnitFileScope scope, const char *root_dir, Presets *pres
continue;
}
rule = (PresetRule) {
rule = (UnitFilePresetRule) {
.pattern = unit_name,
.action = PRESET_ENABLE,
.instances = instances,
@ -2987,7 +2988,7 @@ static int read_presets(UnitFileScope scope, const char *root_dir, Presets *pres
if (!pattern)
return -ENOMEM;
rule = (PresetRule) {
rule = (UnitFilePresetRule) {
.pattern = pattern,
.action = PRESET_DISABLE,
};
@ -3005,14 +3006,15 @@ static int read_presets(UnitFileScope scope, const char *root_dir, Presets *pres
}
}
ps.initialized = true;
*presets = ps;
ps = (Presets){};
ps = (UnitFilePresets){};
return 0;
}
static int pattern_match_multiple_instances(
const PresetRule rule,
const UnitFilePresetRule rule,
const char *unit_name,
char ***ret) {
@ -3066,17 +3068,17 @@ static int pattern_match_multiple_instances(
return 0;
}
static int query_presets(const char *name, const Presets presets, char ***instance_name_list) {
static int query_presets(const char *name, const UnitFilePresets *presets, char ***instance_name_list) {
PresetAction action = PRESET_UNKNOWN;
size_t i;
char **s;
if (!unit_name_is_valid(name, UNIT_NAME_ANY))
return -EINVAL;
for (i = 0; i < presets.n_rules; i++)
if (pattern_match_multiple_instances(presets.rules[i], name, instance_name_list) > 0 ||
fnmatch(presets.rules[i].pattern, name, FNM_NOESCAPE) == 0) {
action = presets.rules[i].action;
for (i = 0; i < presets->n_rules; i++)
if (pattern_match_multiple_instances(presets->rules[i], name, instance_name_list) > 0 ||
fnmatch(presets->rules[i].pattern, name, FNM_NOESCAPE) == 0) {
action = presets->rules[i].action;
break;
}
@ -3099,15 +3101,19 @@ static int query_presets(const char *name, const Presets presets, char ***instan
}
}
int unit_file_query_preset(UnitFileScope scope, const char *root_dir, const char *name) {
_cleanup_(presets_freep) Presets presets = {};
int unit_file_query_preset(UnitFileScope scope, const char *root_dir, const char *name, UnitFilePresets *cached) {
_cleanup_(unit_file_presets_freep) UnitFilePresets tmp = {};
int r;
r = read_presets(scope, root_dir, &presets);
if (r < 0)
return r;
if (!cached)
cached = &tmp;
if (!cached->initialized) {
r = read_presets(scope, root_dir, cached);
if (r < 0)
return r;
}
return query_presets(name, presets, NULL);
return query_presets(name, cached, NULL);
}
static int execute_preset(
@ -3162,7 +3168,7 @@ static int preset_prepare_one(
InstallContext *minus,
LookupPaths *paths,
const char *name,
Presets presets,
const UnitFilePresets *presets,
UnitFileChange **changes,
size_t *n_changes) {
@ -3221,7 +3227,7 @@ int unit_file_preset(
_cleanup_(install_context_done) InstallContext plus = {}, minus = {};
_cleanup_(lookup_paths_free) LookupPaths paths = {};
_cleanup_(presets_freep) Presets presets = {};
_cleanup_(unit_file_presets_freep) UnitFilePresets presets = {};
const char *config_path;
char **i;
int r;
@ -3243,7 +3249,7 @@ int unit_file_preset(
return r;
STRV_FOREACH(i, files) {
r = preset_prepare_one(scope, &plus, &minus, &paths, *i, presets, changes, n_changes);
r = preset_prepare_one(scope, &plus, &minus, &paths, *i, &presets, changes, n_changes);
if (r < 0)
return r;
}
@ -3261,7 +3267,7 @@ int unit_file_preset_all(
_cleanup_(install_context_done) InstallContext plus = {}, minus = {};
_cleanup_(lookup_paths_free) LookupPaths paths = {};
_cleanup_(presets_freep) Presets presets = {};
_cleanup_(unit_file_presets_freep) UnitFilePresets presets = {};
const char *config_path = NULL;
char **i;
int r;
@ -3305,7 +3311,7 @@ int unit_file_preset_all(
continue;
/* we don't pass changes[] in, because we want to handle errors on our own */
r = preset_prepare_one(scope, &plus, &minus, &paths, de->d_name, presets, NULL, 0);
r = preset_prepare_one(scope, &plus, &minus, &paths, de->d_name, &presets, NULL, 0);
if (r == -ERFKILL)
r = unit_file_changes_add(changes, n_changes,
UNIT_FILE_IS_MASKED, de->d_name, NULL);
@ -3344,7 +3350,7 @@ int unit_file_get_list(
char **patterns) {
_cleanup_(lookup_paths_free) LookupPaths paths = {};
char **i;
char **dirname;
int r;
assert(scope >= 0);
@ -3355,16 +3361,16 @@ int unit_file_get_list(
if (r < 0)
return r;
STRV_FOREACH(i, paths.search_path) {
STRV_FOREACH(dirname, paths.search_path) {
_cleanup_closedir_ DIR *d = NULL;
struct dirent *de;
d = opendir(*i);
d = opendir(*dirname);
if (!d) {
if (errno == ENOENT)
continue;
if (IN_SET(errno, ENOTDIR, EACCES)) {
log_debug_errno(errno, "Failed to open \"%s\": %m", *i);
log_debug_errno(errno, "Failed to open \"%s\": %m", *dirname);
continue;
}
@ -3392,7 +3398,7 @@ int unit_file_get_list(
if (!f)
return -ENOMEM;
f->path = path_make_absolute(de->d_name, *i);
f->path = path_make_absolute(de->d_name, *dirname);
if (!f->path)
return -ENOMEM;
@ -3416,34 +3422,35 @@ int unit_file_get_list(
}
static const char* const unit_file_state_table[_UNIT_FILE_STATE_MAX] = {
[UNIT_FILE_ENABLED] = "enabled",
[UNIT_FILE_ENABLED] = "enabled",
[UNIT_FILE_ENABLED_RUNTIME] = "enabled-runtime",
[UNIT_FILE_LINKED] = "linked",
[UNIT_FILE_LINKED_RUNTIME] = "linked-runtime",
[UNIT_FILE_MASKED] = "masked",
[UNIT_FILE_MASKED_RUNTIME] = "masked-runtime",
[UNIT_FILE_STATIC] = "static",
[UNIT_FILE_DISABLED] = "disabled",
[UNIT_FILE_INDIRECT] = "indirect",
[UNIT_FILE_GENERATED] = "generated",
[UNIT_FILE_TRANSIENT] = "transient",
[UNIT_FILE_BAD] = "bad",
[UNIT_FILE_LINKED] = "linked",
[UNIT_FILE_LINKED_RUNTIME] = "linked-runtime",
[UNIT_FILE_ALIAS] = "alias",
[UNIT_FILE_MASKED] = "masked",
[UNIT_FILE_MASKED_RUNTIME] = "masked-runtime",
[UNIT_FILE_STATIC] = "static",
[UNIT_FILE_DISABLED] = "disabled",
[UNIT_FILE_INDIRECT] = "indirect",
[UNIT_FILE_GENERATED] = "generated",
[UNIT_FILE_TRANSIENT] = "transient",
[UNIT_FILE_BAD] = "bad",
};
DEFINE_STRING_TABLE_LOOKUP(unit_file_state, UnitFileState);
static const char* const unit_file_change_type_table[_UNIT_FILE_CHANGE_TYPE_MAX] = {
[UNIT_FILE_SYMLINK] = "symlink",
[UNIT_FILE_UNLINK] = "unlink",
[UNIT_FILE_IS_MASKED] = "masked",
[UNIT_FILE_SYMLINK] = "symlink",
[UNIT_FILE_UNLINK] = "unlink",
[UNIT_FILE_IS_MASKED] = "masked",
[UNIT_FILE_IS_DANGLING] = "dangling",
};
DEFINE_STRING_TABLE_LOOKUP(unit_file_change_type, UnitFileChangeType);
static const char* const unit_file_preset_mode_table[_UNIT_FILE_PRESET_MAX] = {
[UNIT_FILE_PRESET_FULL] = "full",
[UNIT_FILE_PRESET_ENABLE_ONLY] = "enable-only",
[UNIT_FILE_PRESET_FULL] = "full",
[UNIT_FILE_PRESET_ENABLE_ONLY] = "enable-only",
[UNIT_FILE_PRESET_DISABLE_ONLY] = "disable-only",
};

View File

@ -189,7 +189,16 @@ void unit_file_dump_changes(int r, const char *verb, const UnitFileChange *chang
int unit_file_verify_alias(const UnitFileInstallInfo *i, const char *dst, char **ret_dst);
int unit_file_query_preset(UnitFileScope scope, const char *root_dir, const char *name);
typedef struct UnitFilePresetRule UnitFilePresetRule;
typedef struct {
UnitFilePresetRule *rules;
size_t n_rules;
bool initialized;
} UnitFilePresets;
void unit_file_presets_freep(UnitFilePresets *p);
int unit_file_query_preset(UnitFileScope scope, const char *root_dir, const char *name, UnitFilePresets *cached);
const char *unit_file_state_to_string(UnitFileState s) _const_;
UnitFileState unit_file_state_from_string(const char *s) _pure_;

View File

@ -320,7 +320,7 @@ int unit_file_build_name_map(
/* We don't explicitly check for alias loops here. unit_ids_map_get() which
* limits the number of hops should be used to access the map. */
_cleanup_free_ char *target = NULL, *target_abs = NULL;
_cleanup_free_ char *target = NULL;
r = readlinkat_malloc(dirfd(d), de->d_name, &target);
if (r < 0) {
@ -329,8 +329,9 @@ int unit_file_build_name_map(
continue;
}
if (!path_is_absolute(target)) {
target_abs = path_join(*dir, target);
const bool is_abs = path_is_absolute(target);
if (lp->root_dir || !is_abs) {
char *target_abs = path_join(is_abs ? lp->root_dir : *dir, target);
if (!target_abs)
return log_oom();

View File

@ -16,6 +16,7 @@ enum UnitFileState {
UNIT_FILE_ENABLED_RUNTIME,
UNIT_FILE_LINKED,
UNIT_FILE_LINKED_RUNTIME,
UNIT_FILE_ALIAS,
UNIT_FILE_MASKED,
UNIT_FILE_MASKED_RUNTIME,
UNIT_FILE_STATIC,

View File

@ -45,10 +45,19 @@ bool running_in_chroot_or_offline(void) {
return r > 0;
}
const Verb* verbs_find_verb(const char *name, const Verb verbs[]) {
for (size_t i = 0; verbs[i].dispatch; i++)
if (streq_ptr(name, verbs[i].verb) ||
(!name && FLAGS_SET(verbs[i].flags, VERB_DEFAULT)))
return &verbs[i];
/* At the end of the list? */
return NULL;
}
int dispatch_verb(int argc, char *argv[], const Verb verbs[], void *userdata) {
const Verb *verb;
const char *name;
unsigned i;
int left;
assert(verbs);
@ -62,31 +71,16 @@ int dispatch_verb(int argc, char *argv[], const Verb verbs[], void *userdata) {
optind = 0;
name = argv[0];
for (i = 0;; i++) {
bool found;
/* At the end of the list? */
if (!verbs[i].dispatch) {
if (name)
log_error("Unknown operation %s.", name);
else
log_error("Requires operation parameter.");
return -EINVAL;
}
verb = verbs_find_verb(name, verbs);
if (!verb) {
if (name)
found = streq(name, verbs[i].verb);
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
"Unknown command verb %s.", name);
else
found = verbs[i].flags & VERB_DEFAULT;
if (found) {
verb = &verbs[i];
break;
}
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
"Command verb required.");
}
assert(verb);
if (!name)
left = 1;
@ -101,10 +95,7 @@ int dispatch_verb(int argc, char *argv[], const Verb verbs[], void *userdata) {
"Too many arguments.");
if ((verb->flags & VERB_ONLINE_ONLY) && running_in_chroot_or_offline()) {
if (name)
log_info("Running in chroot, ignoring request: %s", name);
else
log_info("Running in chroot, ignoring request.");
log_info("Running in chroot, ignoring command '%s'", name ?: verb->verb);
return 0;
}

View File

@ -6,8 +6,8 @@
#define VERB_ANY ((unsigned) -1)
typedef enum VerbFlags {
VERB_DEFAULT = 1 << 0,
VERB_ONLINE_ONLY = 1 << 1,
VERB_DEFAULT = 1 << 0, /* The verb to run if no verb is specified */
VERB_ONLINE_ONLY = 1 << 1, /* Just do nothing when running in chroot or offline */
} VerbFlags;
typedef struct {
@ -19,4 +19,5 @@ typedef struct {
bool running_in_chroot_or_offline(void);
const Verb* verbs_find_verb(const char *name, const Verb verbs[]);
int dispatch_verb(int argc, char *argv[], const Verb verbs[], void *userdata);

View File

@ -31,10 +31,12 @@
static unsigned arg_connections_max = 256;
static const char *arg_remote_host = NULL;
static usec_t arg_exit_idle_time = USEC_INFINITY;
typedef struct Context {
sd_event *event;
sd_resolve *resolve;
sd_event_source *idle_time;
Set *listen;
Set *connections;
@ -75,6 +77,51 @@ static void connection_free(Connection *c) {
free(c);
}
static int idle_time_cb(sd_event_source *s, uint64_t usec, void *userdata) {
Context *c = userdata;
int r;
if (!set_isempty(c->connections)) {
log_warning("Idle timer fired even though there are connections, ignoring");
return 0;
}
r = sd_event_exit(c->event, 0);
if (r < 0) {
log_warning_errno(r, "Error while stopping event loop, ignoring: %m");
return 0;
}
return 0;
}
static int connection_release(Connection *c) {
int r;
Context *context = c->context;
usec_t idle_instant;
connection_free(c);
if (arg_exit_idle_time < USEC_INFINITY && set_isempty(context->connections)) {
idle_instant = usec_add(now(CLOCK_MONOTONIC), arg_exit_idle_time);
if (context->idle_time) {
r = sd_event_source_set_time(context->idle_time, idle_instant);
if (r < 0)
return log_error_errno(r, "Error while setting idle time: %m");
r = sd_event_source_set_enabled(context->idle_time, SD_EVENT_ONESHOT);
if (r < 0)
return log_error_errno(r, "Error while enabling idle time: %m");
} else {
r = sd_event_add_time(context->event, &context->idle_time, CLOCK_MONOTONIC,
idle_instant, 0, idle_time_cb, context);
if (r < 0)
return log_error_errno(r, "Failed to create idle timer: %m");
}
}
return 0;
}
static void context_clear(Context *context) {
assert(context);
@ -83,6 +130,7 @@ static void context_clear(Context *context) {
sd_event_unref(context->event);
sd_resolve_unref(context->resolve);
sd_event_source_unref(context->idle_time);
}
static int connection_create_pipes(Connection *c, int buffer[static 2], size_t *sz) {
@ -206,7 +254,7 @@ static int traffic_cb(sd_event_source *s, int fd, uint32_t revents, void *userda
return 1;
quit:
connection_free(c);
connection_release(c);
return 0; /* ignore errors, continue serving */
}
@ -269,7 +317,7 @@ static int connection_complete(Connection *c) {
return 0;
fail:
connection_free(c);
connection_release(c);
return 0; /* ignore errors, continue serving */
}
@ -299,7 +347,7 @@ static int connect_cb(sd_event_source *s, int fd, uint32_t revents, void *userda
return connection_complete(c);
fail:
connection_free(c);
connection_release(c);
return 0; /* ignore errors, continue serving */
}
@ -343,7 +391,7 @@ static int connection_start(Connection *c, struct sockaddr *sa, socklen_t salen)
return 0;
fail:
connection_free(c);
connection_release(c);
return 0; /* ignore errors, continue serving */
}
@ -361,7 +409,7 @@ static int resolve_handler(sd_resolve_query *q, int ret, const struct addrinfo *
return connection_start(c, ai->ai_addr, ai->ai_addrlen);
fail:
connection_free(c);
connection_release(c);
return 0; /* ignore errors, continue serving */
}
@ -409,7 +457,7 @@ static int resolve_remote(Connection *c) {
return 0;
fail:
connection_free(c);
connection_release(c);
return 0; /* ignore errors, continue serving */
}
@ -426,6 +474,12 @@ static int add_connection_socket(Context *context, int fd) {
return 0;
}
if (context->idle_time) {
r = sd_event_source_set_enabled(context->idle_time, SD_EVENT_OFF);
if (r < 0)
log_warning_errno(r, "Unable to disable idle timer, continuing: %m");
}
r = set_ensure_allocated(&context->connections, NULL);
if (r < 0) {
log_oom();
@ -535,9 +589,13 @@ static int add_listen_socket(Context *context, int fd) {
static int help(void) {
_cleanup_free_ char *link = NULL;
_cleanup_free_ char *time_link = NULL;
int r;
r = terminal_urlify_man("systemd-socket-proxyd", "8", &link);
if (r < 0)
return log_oom();
r = terminal_urlify_man("systemd.time", "7", &time_link);
if (r < 0)
return log_oom();
@ -545,11 +603,14 @@ static int help(void) {
"%1$s [SOCKET]\n\n"
"Bidirectionally proxy local sockets to another (possibly remote) socket.\n\n"
" -c --connections-max= Set the maximum number of connections to be accepted\n"
" --exit-idle-time= Exit when without a connection for this duration. See\n"
" the %3$s for time span format\n"
" -h --help Show this help\n"
" --version Show package version\n"
"\nSee the %2$s for details.\n"
, program_invocation_short_name
, link
, time_link
);
return 0;
@ -559,11 +620,13 @@ static int parse_argv(int argc, char *argv[]) {
enum {
ARG_VERSION = 0x100,
ARG_EXIT_IDLE,
ARG_IGNORE_ENV
};
static const struct option options[] = {
{ "connections-max", required_argument, NULL, 'c' },
{ "exit-idle-time", required_argument, NULL, ARG_EXIT_IDLE },
{ "help", no_argument, NULL, 'h' },
{ "version", no_argument, NULL, ARG_VERSION },
{}
@ -597,6 +660,12 @@ static int parse_argv(int argc, char *argv[]) {
break;
case ARG_EXIT_IDLE:
r = parse_sec(optarg, &arg_exit_idle_time);
if (r < 0)
return log_error_errno(r, "Failed to parse --exit-idle-time= argument: %s", optarg);
break;
case '?':
return -EINVAL;

View File

@ -1456,9 +1456,18 @@ static bool output_show_unit_file(const UnitFileList *u, char **states, char **p
return true;
}
static bool show_preset_for_state(UnitFileState state) {
/* Don't show preset state in those unit file states, it'll only confuse users. */
return !IN_SET(state,
UNIT_FILE_ALIAS,
UNIT_FILE_STATIC,
UNIT_FILE_GENERATED,
UNIT_FILE_TRANSIENT);
}
static int output_unit_file_list(const UnitFileList *units, unsigned c) {
_cleanup_(table_unrefp) Table *table = NULL;
const UnitFileList *u;
_cleanup_(unit_file_presets_freep) UnitFilePresets presets = {};
int r;
table = table_new("unit file", "state", "vendor preset");
@ -1469,9 +1478,8 @@ static int output_unit_file_list(const UnitFileList *units, unsigned c) {
if (arg_full)
table_set_width(table, 0);
for (u = units; u < units + c; u++) {
for (const UnitFileList *u = units; u < units + c; u++) {
const char *on_underline = NULL, *on_unit_color = NULL, *id;
const char *on_preset_color = NULL, *unit_preset_str;
bool underline;
underline = u + 1 < units + c &&
@ -1486,32 +1494,44 @@ static int output_unit_file_list(const UnitFileList *units, unsigned c) {
UNIT_FILE_DISABLED,
UNIT_FILE_BAD))
on_unit_color = underline ? ansi_highlight_red_underline() : ansi_highlight_red();
else if (u->state == UNIT_FILE_ENABLED)
else if (IN_SET(u->state,
UNIT_FILE_ENABLED,
UNIT_FILE_ALIAS))
on_unit_color = underline ? ansi_highlight_green_underline() : ansi_highlight_green();
else
on_unit_color = on_underline;
id = basename(u->path);
r = unit_file_query_preset(arg_scope, NULL, id);
if (r < 0) {
unit_preset_str = "n/a";
on_preset_color = underline ? on_underline : ansi_normal();
} else if (r == 0) {
unit_preset_str = "disabled";
on_preset_color = underline ? ansi_highlight_red_underline() : ansi_highlight_red();
} else {
unit_preset_str = "enabled";
on_preset_color = underline ? ansi_highlight_green_underline() : ansi_highlight_green();
}
r = table_add_many(table,
TABLE_STRING, id,
TABLE_SET_COLOR, strempty(on_underline),
TABLE_STRING, unit_file_state_to_string(u->state),
TABLE_SET_COLOR, strempty(on_unit_color),
TABLE_STRING, unit_preset_str,
TABLE_SET_COLOR, strempty(on_preset_color));
TABLE_SET_COLOR, strempty(on_unit_color));
if (r < 0)
return table_log_add_error(r);
if (show_preset_for_state(u->state)) {
const char *unit_preset_str, *on_preset_color;
r = unit_file_query_preset(arg_scope, arg_root, id, &presets);
if (r < 0) {
unit_preset_str = "n/a";
on_preset_color = underline ? on_underline : ansi_normal();
} else if (r == 0) {
unit_preset_str = "disabled";
on_preset_color = underline ? ansi_highlight_red_underline() : ansi_highlight_red();
} else {
unit_preset_str = "enabled";
on_preset_color = underline ? ansi_highlight_green_underline() : ansi_highlight_green();
}
r = table_add_many(table,
TABLE_STRING, unit_preset_str,
TABLE_SET_COLOR, strempty(on_preset_color));
} else
r = table_add_many(table, TABLE_EMPTY);
if (r < 0)
return table_log_add_error(r);
}
@ -4246,14 +4266,18 @@ static void print_status_info(
if (!isempty(i->load_error))
printf(" Loaded: %s%s%s (Reason: %s)\n",
on, strna(i->load_state), off, i->load_error);
else if (path && !isempty(i->unit_file_state) && !isempty(i->unit_file_preset) &&
!STR_IN_SET(i->unit_file_state, "generated", "transient"))
printf(" Loaded: %s%s%s (%s; %s; vendor preset: %s)\n",
on, strna(i->load_state), off, path, i->unit_file_state, i->unit_file_preset);
else if (path && !isempty(i->unit_file_state))
printf(" Loaded: %s%s%s (%s; %s)\n",
on, strna(i->load_state), off, path, i->unit_file_state);
else if (path)
else if (path && !isempty(i->unit_file_state)) {
bool show_preset = !isempty(i->unit_file_preset) &&
show_preset_for_state(unit_file_state_from_string(i->unit_file_state));
printf(" Loaded: %s%s%s (%s; %s%s%s)\n",
on, strna(i->load_state), off,
path,
i->unit_file_state,
show_preset ? "; vendor preset: " : "",
show_preset ? i->unit_file_preset : "");
} else if (path)
printf(" Loaded: %s%s%s (%s)\n",
on, strna(i->load_state), off, path);
else
@ -5892,7 +5916,8 @@ static int show(int argc, char *argv[], void *userdata) {
if (show_mode == SYSTEMCTL_SHOW_HELP && argc <= 1)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
"This command expects one or more unit names. Did you mean --help?");
"'help' command expects one or more unit names.\n"
"(Alternatively, help for systemctl itself may be shown with --help)");
r = acquire_bus(BUS_MANAGER, &bus);
if (r < 0)
@ -7367,6 +7392,7 @@ static int unit_is_enabled(int argc, char *argv[], void *userdata) {
UNIT_FILE_ENABLED,
UNIT_FILE_ENABLED_RUNTIME,
UNIT_FILE_STATIC,
UNIT_FILE_ALIAS,
UNIT_FILE_INDIRECT,
UNIT_FILE_GENERATED))
enabled = true;
@ -9211,9 +9237,9 @@ static int systemctl_main(int argc, char *argv[]) {
{ "help", VERB_ANY, VERB_ANY, VERB_ONLINE_ONLY, show },
{ "daemon-reload", VERB_ANY, 1, VERB_ONLINE_ONLY, daemon_reload },
{ "daemon-reexec", VERB_ANY, 1, VERB_ONLINE_ONLY, daemon_reload },
{ "log-level", VERB_ANY, 2, 0, log_level },
{ "log-target", VERB_ANY, 2, 0, log_target },
{ "service-watchdogs", VERB_ANY, 2, 0, service_watchdogs },
{ "log-level", VERB_ANY, 2, VERB_ONLINE_ONLY, log_level },
{ "log-target", VERB_ANY, 2, VERB_ONLINE_ONLY, log_target },
{ "service-watchdogs", VERB_ANY, 2, VERB_ONLINE_ONLY, service_watchdogs },
{ "show-environment", VERB_ANY, 1, VERB_ONLINE_ONLY, show_environment },
{ "set-environment", 2, VERB_ANY, VERB_ONLINE_ONLY, set_environment },
{ "unset-environment", 2, VERB_ANY, VERB_ONLINE_ONLY, set_environment },
@ -9253,6 +9279,12 @@ static int systemctl_main(int argc, char *argv[]) {
{}
};
const Verb *verb = verbs_find_verb(argv[optind], verbs);
if (verb && (verb->flags & VERB_ONLINE_ONLY) && arg_root)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
"Verb '%s' cannot be used with --root=.",
argv[optind] ?: verb->verb);
return dispatch_verb(argc, argv, verbs, NULL);
}

View File

@ -187,6 +187,124 @@ struct sd_bus_vtable {
.x = { { 0 } }, \
}
#define _SD_ECHO(X) X
#define _SD_CONCAT(X) #X "\0"
#define _SD_VARARGS_FOREACH_EVEN_01(FN, X, ...)
#define _SD_VARARGS_FOREACH_EVEN_02(FN, X, ...) FN(X) _SD_VARARGS_FOREACH_EVEN_01(FN, __VA_ARGS__)
#define _SD_VARARGS_FOREACH_EVEN_03(FN, X, ...) _SD_VARARGS_FOREACH_EVEN_02(FN, __VA_ARGS__)
#define _SD_VARARGS_FOREACH_EVEN_04(FN, X, ...) FN(X) _SD_VARARGS_FOREACH_EVEN_03(FN, __VA_ARGS__)
#define _SD_VARARGS_FOREACH_EVEN_05(FN, X, ...) _SD_VARARGS_FOREACH_EVEN_04(FN, __VA_ARGS__)
#define _SD_VARARGS_FOREACH_EVEN_06(FN, X, ...) FN(X) _SD_VARARGS_FOREACH_EVEN_05(FN, __VA_ARGS__)
#define _SD_VARARGS_FOREACH_EVEN_07(FN, X, ...) _SD_VARARGS_FOREACH_EVEN_06(FN, __VA_ARGS__)
#define _SD_VARARGS_FOREACH_EVEN_08(FN, X, ...) FN(X) _SD_VARARGS_FOREACH_EVEN_07(FN, __VA_ARGS__)
#define _SD_VARARGS_FOREACH_EVEN_09(FN, X, ...) _SD_VARARGS_FOREACH_EVEN_08(FN, __VA_ARGS__)
#define _SD_VARARGS_FOREACH_EVEN_10(FN, X, ...) FN(X) _SD_VARARGS_FOREACH_EVEN_09(FN, __VA_ARGS__)
#define _SD_VARARGS_FOREACH_EVEN_11(FN, X, ...) _SD_VARARGS_FOREACH_EVEN_10(FN, __VA_ARGS__)
#define _SD_VARARGS_FOREACH_EVEN_12(FN, X, ...) FN(X) _SD_VARARGS_FOREACH_EVEN_11(FN, __VA_ARGS__)
#define _SD_VARARGS_FOREACH_EVEN_13(FN, X, ...) _SD_VARARGS_FOREACH_EVEN_12(FN, __VA_ARGS__)
#define _SD_VARARGS_FOREACH_EVEN_14(FN, X, ...) FN(X) _SD_VARARGS_FOREACH_EVEN_13(FN, __VA_ARGS__)
#define _SD_VARARGS_FOREACH_EVEN_15(FN, X, ...) _SD_VARARGS_FOREACH_EVEN_14(FN, __VA_ARGS__)
#define _SD_VARARGS_FOREACH_EVEN_16(FN, X, ...) FN(X) _SD_VARARGS_FOREACH_EVEN_15(FN, __VA_ARGS__)
#define _SD_VARARGS_FOREACH_EVEN_17(FN, X, ...) _SD_VARARGS_FOREACH_EVEN_16(FN, __VA_ARGS__)
#define _SD_VARARGS_FOREACH_EVEN_18(FN, X, ...) FN(X) _SD_VARARGS_FOREACH_EVEN_17(FN, __VA_ARGS__)
#define _SD_VARARGS_FOREACH_EVEN_19(FN, X, ...) _SD_VARARGS_FOREACH_EVEN_18(FN, __VA_ARGS__)
#define _SD_VARARGS_FOREACH_EVEN_20(FN, X, ...) FN(X) _SD_VARARGS_FOREACH_EVEN_19(FN, __VA_ARGS__)
#define _SD_VARARGS_FOREACH_EVEN_21(FN, X, ...) _SD_VARARGS_FOREACH_EVEN_20(FN, __VA_ARGS__)
#define _SD_VARARGS_FOREACH_EVEN_22(FN, X, ...) FN(X) _SD_VARARGS_FOREACH_EVEN_21(FN, __VA_ARGS__)
#define _SD_VARARGS_FOREACH_EVEN_23(FN, X, ...) _SD_VARARGS_FOREACH_EVEN_22(FN, __VA_ARGS__)
#define _SD_VARARGS_FOREACH_EVEN_24(FN, X, ...) FN(X) _SD_VARARGS_FOREACH_EVEN_23(FN, __VA_ARGS__)
#define _SD_VARARGS_FOREACH_EVEN_25(FN, X, ...) _SD_VARARGS_FOREACH_EVEN_24(FN, __VA_ARGS__)
#define _SD_VARARGS_FOREACH_EVEN_26(FN, X, ...) FN(X) _SD_VARARGS_FOREACH_EVEN_25(FN, __VA_ARGS__)
#define _SD_VARARGS_FOREACH_EVEN_27(FN, X, ...) _SD_VARARGS_FOREACH_EVEN_26(FN, __VA_ARGS__)
#define _SD_VARARGS_FOREACH_EVEN_28(FN, X, ...) FN(X) _SD_VARARGS_FOREACH_EVEN_27(FN, __VA_ARGS__)
#define _SD_VARARGS_FOREACH_EVEN_29(FN, X, ...) _SD_VARARGS_FOREACH_EVEN_28(FN, __VA_ARGS__)
#define _SD_VARARGS_FOREACH_EVEN_30(FN, X, ...) FN(X) _SD_VARARGS_FOREACH_EVEN_29(FN, __VA_ARGS__)
#define _SD_VARARGS_FOREACH_EVEN_31(FN, X, ...) _SD_VARARGS_FOREACH_EVEN_30(FN, __VA_ARGS__)
#define _SD_VARARGS_FOREACH_EVEN_32(FN, X, ...) FN(X) _SD_VARARGS_FOREACH_EVEN_31(FN, __VA_ARGS__)
#define _SD_VARARGS_FOREACH_EVEN_33(FN, X, ...) _SD_VARARGS_FOREACH_EVEN_32(FN, __VA_ARGS__)
#define _SD_VARARGS_FOREACH_EVEN_34(FN, X, ...) FN(X) _SD_VARARGS_FOREACH_EVEN_33(FN, __VA_ARGS__)
#define _SD_VARARGS_FOREACH_EVEN_35(FN, X, ...) _SD_VARARGS_FOREACH_EVEN_34(FN, __VA_ARGS__)
#define _SD_VARARGS_FOREACH_EVEN_36(FN, X, ...) FN(X) _SD_VARARGS_FOREACH_EVEN_35(FN, __VA_ARGS__)
#define _SD_VARARGS_FOREACH_EVEN_37(FN, X, ...) _SD_VARARGS_FOREACH_EVEN_36(FN, __VA_ARGS__)
#define _SD_VARARGS_FOREACH_EVEN_38(FN, X, ...) FN(X) _SD_VARARGS_FOREACH_EVEN_37(FN, __VA_ARGS__)
#define _SD_VARARGS_FOREACH_EVEN_39(FN, X, ...) _SD_VARARGS_FOREACH_EVEN_38(FN, __VA_ARGS__)
#define _SD_VARARGS_FOREACH_EVEN_40(FN, X, ...) FN(X) _SD_VARARGS_FOREACH_EVEN_39(FN, __VA_ARGS__)
#define _SD_VARARGS_FOREACH_EVEN_41(FN, X, ...) _SD_VARARGS_FOREACH_EVEN_40(FN, __VA_ARGS__)
#define _SD_VARARGS_FOREACH_EVEN_42(FN, X, ...) FN(X) _SD_VARARGS_FOREACH_EVEN_41(FN, __VA_ARGS__)
#define _SD_VARARGS_FOREACH_EVEN_43(FN, X, ...) _SD_VARARGS_FOREACH_EVEN_42(FN, __VA_ARGS__)
#define _SD_VARARGS_FOREACH_EVEN_44(FN, X, ...) FN(X) _SD_VARARGS_FOREACH_EVEN_43(FN, __VA_ARGS__)
#define _SD_VARARGS_FOREACH_EVEN_45(FN, X, ...) _SD_VARARGS_FOREACH_EVEN_44(FN, __VA_ARGS__)
#define _SD_VARARGS_FOREACH_EVEN_46(FN, X, ...) FN(X) _SD_VARARGS_FOREACH_EVEN_45(FN, __VA_ARGS__)
#define _SD_VARARGS_FOREACH_EVEN_47(FN, X, ...) _SD_VARARGS_FOREACH_EVEN_46(FN, __VA_ARGS__)
#define _SD_VARARGS_FOREACH_EVEN_48(FN, X, ...) FN(X) _SD_VARARGS_FOREACH_EVEN_47(FN, __VA_ARGS__)
#define _SD_VARARGS_FOREACH_EVEN_49(FN, X, ...) _SD_VARARGS_FOREACH_EVEN_48(FN, __VA_ARGS__)
#define _SD_VARARGS_FOREACH_EVEN_50(FN, X, ...) FN(X) _SD_VARARGS_FOREACH_EVEN_49(FN, __VA_ARGS__)
#define _SD_VARARGS_FOREACH_EVEN_SEQ(_01, _02, _03, _04, _05, _06, _07, _08, _09, _10, \
_11, _12, _13, _14, _15, _16, _17, _18, _19, _20, \
_21, _22, _23, _24, _25, _26, _27, _28, _29, _30, \
_31, _32, _33, _34, _35, _36, _37, _38, _39, _40, \
_41, _42, _43, _44, _45, _46, _47, _48, _49, _50, \
NAME, ...) NAME
#define _SD_VARARGS_FOREACH_EVEN(FN, ...) \
_SD_VARARGS_FOREACH_EVEN_SEQ(__VA_ARGS__, \
_SD_VARARGS_FOREACH_EVEN_50, _SD_VARARGS_FOREACH_EVEN_49, \
_SD_VARARGS_FOREACH_EVEN_48, _SD_VARARGS_FOREACH_EVEN_47, \
_SD_VARARGS_FOREACH_EVEN_46, _SD_VARARGS_FOREACH_EVEN_45, \
_SD_VARARGS_FOREACH_EVEN_44, _SD_VARARGS_FOREACH_EVEN_43, \
_SD_VARARGS_FOREACH_EVEN_42, _SD_VARARGS_FOREACH_EVEN_41, \
_SD_VARARGS_FOREACH_EVEN_40, _SD_VARARGS_FOREACH_EVEN_39, \
_SD_VARARGS_FOREACH_EVEN_38, _SD_VARARGS_FOREACH_EVEN_37, \
_SD_VARARGS_FOREACH_EVEN_36, _SD_VARARGS_FOREACH_EVEN_35, \
_SD_VARARGS_FOREACH_EVEN_34, _SD_VARARGS_FOREACH_EVEN_33, \
_SD_VARARGS_FOREACH_EVEN_32, _SD_VARARGS_FOREACH_EVEN_31, \
_SD_VARARGS_FOREACH_EVEN_30, _SD_VARARGS_FOREACH_EVEN_29, \
_SD_VARARGS_FOREACH_EVEN_28, _SD_VARARGS_FOREACH_EVEN_27, \
_SD_VARARGS_FOREACH_EVEN_26, _SD_VARARGS_FOREACH_EVEN_25, \
_SD_VARARGS_FOREACH_EVEN_24, _SD_VARARGS_FOREACH_EVEN_23, \
_SD_VARARGS_FOREACH_EVEN_22, _SD_VARARGS_FOREACH_EVEN_21, \
_SD_VARARGS_FOREACH_EVEN_20, _SD_VARARGS_FOREACH_EVEN_19, \
_SD_VARARGS_FOREACH_EVEN_18, _SD_VARARGS_FOREACH_EVEN_17, \
_SD_VARARGS_FOREACH_EVEN_16, _SD_VARARGS_FOREACH_EVEN_15, \
_SD_VARARGS_FOREACH_EVEN_14, _SD_VARARGS_FOREACH_EVEN_13, \
_SD_VARARGS_FOREACH_EVEN_12, _SD_VARARGS_FOREACH_EVEN_11, \
_SD_VARARGS_FOREACH_EVEN_10, _SD_VARARGS_FOREACH_EVEN_09, \
_SD_VARARGS_FOREACH_EVEN_08, _SD_VARARGS_FOREACH_EVEN_07, \
_SD_VARARGS_FOREACH_EVEN_06, _SD_VARARGS_FOREACH_EVEN_05, \
_SD_VARARGS_FOREACH_EVEN_04, _SD_VARARGS_FOREACH_EVEN_03, \
_SD_VARARGS_FOREACH_EVEN_02, _SD_VARARGS_FOREACH_EVEN_01) \
(FN, __VA_ARGS__)
#define SD_BUS_ARGS(...) __VA_ARGS__
#define SD_BUS_RESULT(...) __VA_ARGS__
#define SD_BUS_NO_ARGS SD_BUS_ARGS(NULL,)
#define SD_BUS_NO_RESULT SD_BUS_RESULT(NULL,)
#define SD_BUS_METHOD_WITH_ARGS(_member, _args, _result, _handler, _flags) \
SD_BUS_METHOD_WITH_NAMES(_member, \
_SD_VARARGS_FOREACH_EVEN(_SD_ECHO, _args), \
_SD_VARARGS_FOREACH_EVEN(_SD_CONCAT, _args, ""), \
_SD_VARARGS_FOREACH_EVEN(_SD_ECHO, _result), \
_SD_VARARGS_FOREACH_EVEN(_SD_CONCAT, _result, ""), \
_handler, _flags)
#define SD_BUS_METHOD_WITH_ARGS_OFFSET(_member, _args, _result, _handler, _offset, _flags) \
SD_BUS_METHOD_WITH_NAMES_OFFSET(_member, \
_SD_VARARGS_FOREACH_EVEN(_SD_ECHO, _args), \
_SD_VARARGS_FOREACH_EVEN(_SD_CONCAT, _args, ""), \
_SD_VARARGS_FOREACH_EVEN(_SD_ECHO, _result), \
_SD_VARARGS_FOREACH_EVEN(_SD_CONCAT, _result, ""), \
_handler, _offset, _flags)
#define SD_BUS_SIGNAL_WITH_ARGS(_member, _args, _flags) \
SD_BUS_SIGNAL_WITH_NAMES(_member, \
_SD_VARARGS_FOREACH_EVEN(_SD_ECHO, _args), \
_SD_VARARGS_FOREACH_EVEN(_SD_CONCAT, _args, ""), \
_flags)
_SD_END_DECLARATIONS;
#endif

View File

@ -529,7 +529,7 @@ static int write_temporary_shadow(const char *shadow_path, FILE **tmpfile, char
ORDERED_HASHMAP_FOREACH(i, todo_uids, iterator) {
struct spwd n = {
.sp_namp = i->name,
.sp_pwdp = (char*) "!!", /* lock this password, and make it invalid */
.sp_pwdp = (char*) "!*", /* lock this password, and make it invalid */
.sp_lstchg = lstchg,
.sp_min = -1,
.sp_max = -1,

View File

@ -36,20 +36,20 @@ static void test_basic_mask_and_enable(const char *root) {
assert_se(symlink("a.service", p) >= 0);
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "b.service", NULL) >= 0);
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "b.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "b.service", &state) >= 0 && state == UNIT_FILE_ALIAS);
p = strjoina(root, "/usr/lib/systemd/system/c.service");
assert_se(symlink("/usr/lib/systemd/system/a.service", p) >= 0);
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "c.service", NULL) >= 0);
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "c.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "c.service", &state) >= 0 && state == UNIT_FILE_ALIAS);
p = strjoina(root, "/usr/lib/systemd/system/d.service");
assert_se(symlink("c.service", p) >= 0);
/* This one is interesting, as d follows a relative, then an absolute symlink */
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "d.service", NULL) >= 0);
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "d.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "d.service", &state) >= 0 && state == UNIT_FILE_ALIAS);
assert_se(unit_file_mask(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("a.service"), &changes, &n_changes) >= 0);
assert_se(n_changes == 1);
@ -89,9 +89,9 @@ static void test_basic_mask_and_enable(const char *root) {
changes = NULL; n_changes = 0;
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "a.service", &state) >= 0 && state == UNIT_FILE_ENABLED);
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "b.service", &state) >= 0 && state == UNIT_FILE_ENABLED);
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "c.service", &state) >= 0 && state == UNIT_FILE_ENABLED);
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "d.service", &state) >= 0 && state == UNIT_FILE_ENABLED);
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "b.service", &state) >= 0 && state == UNIT_FILE_ALIAS);
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "c.service", &state) >= 0 && state == UNIT_FILE_ALIAS);
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "d.service", &state) >= 0 && state == UNIT_FILE_ALIAS);
/* Enabling it again should succeed but be a NOP */
assert_se(unit_file_enable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("a.service"), &changes, &n_changes) >= 0);
@ -108,9 +108,9 @@ static void test_basic_mask_and_enable(const char *root) {
changes = NULL; n_changes = 0;
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "a.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "b.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "c.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "d.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "b.service", &state) >= 0 && state == UNIT_FILE_ALIAS);
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "c.service", &state) >= 0 && state == UNIT_FILE_ALIAS);
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "d.service", &state) >= 0 && state == UNIT_FILE_ALIAS);
/* Disabling a disabled unit must succeed but be a NOP */
assert_se(unit_file_disable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("a.service"), &changes, &n_changes) >= 0);
@ -129,9 +129,9 @@ static void test_basic_mask_and_enable(const char *root) {
changes = NULL; n_changes = 0;
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "a.service", &state) >= 0 && state == UNIT_FILE_ENABLED);
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "b.service", &state) >= 0 && state == UNIT_FILE_ENABLED);
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "c.service", &state) >= 0 && state == UNIT_FILE_ENABLED);
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "d.service", &state) >= 0 && state == UNIT_FILE_ENABLED);
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "b.service", &state) >= 0 && state == UNIT_FILE_ALIAS);
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "c.service", &state) >= 0 && state == UNIT_FILE_ALIAS);
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "d.service", &state) >= 0 && state == UNIT_FILE_ALIAS);
/* Let's try to reenable */
@ -147,9 +147,9 @@ static void test_basic_mask_and_enable(const char *root) {
changes = NULL; n_changes = 0;
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "a.service", &state) >= 0 && state == UNIT_FILE_ENABLED);
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "b.service", &state) >= 0 && state == UNIT_FILE_ENABLED);
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "c.service", &state) >= 0 && state == UNIT_FILE_ENABLED);
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "d.service", &state) >= 0 && state == UNIT_FILE_ENABLED);
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "b.service", &state) >= 0 && state == UNIT_FILE_ALIAS);
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "c.service", &state) >= 0 && state == UNIT_FILE_ALIAS);
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "d.service", &state) >= 0 && state == UNIT_FILE_ALIAS);
}
static void test_linked_units(const char *root) {
@ -386,7 +386,7 @@ static void test_template_enable(const char *root) {
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template@.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template@def.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template@foo.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template-symlink@.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template-symlink@.service", &state) >= 0 && state == UNIT_FILE_ALIAS);
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template-symlink@def.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template-symlink@foo.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
@ -404,7 +404,7 @@ static void test_template_enable(const char *root) {
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template@.service", &state) >= 0 && state == UNIT_FILE_ENABLED);
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template@def.service", &state) >= 0 && state == UNIT_FILE_ENABLED);
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template@foo.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template-symlink@.service", &state) >= 0 && state == UNIT_FILE_ENABLED);
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template-symlink@.service", &state) >= 0 && state == UNIT_FILE_ALIAS);
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template-symlink@def.service", &state) >= 0 && state == UNIT_FILE_ENABLED);
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template-symlink@foo.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
@ -418,7 +418,7 @@ static void test_template_enable(const char *root) {
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template@.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template@def.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template@foo.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template-symlink@.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template-symlink@.service", &state) >= 0 && state == UNIT_FILE_ALIAS);
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template-symlink@def.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template-symlink@foo.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
@ -450,7 +450,7 @@ static void test_template_enable(const char *root) {
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template@def.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template@foo.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template@quux.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template-symlink@.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template-symlink@.service", &state) >= 0 && state == UNIT_FILE_ALIAS);
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template-symlink@def.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template-symlink@foo.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template-symlink@quux.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
@ -469,7 +469,7 @@ static void test_template_enable(const char *root) {
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template@def.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template@foo.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template@quux.service", &state) >= 0 && state == UNIT_FILE_ENABLED);
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template-symlink@.service", &state) >= 0 && state == UNIT_FILE_INDIRECT);
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template-symlink@.service", &state) >= 0 && state == UNIT_FILE_ALIAS);
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template-symlink@def.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template-symlink@foo.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template-symlink@quux.service", &state) >= 0 && state == UNIT_FILE_ENABLED);
@ -500,7 +500,7 @@ static void test_indirect(const char *root) {
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "indirecta.service", &state) >= 0 && state == UNIT_FILE_INDIRECT);
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "indirectb.service", &state) >= 0 && state == UNIT_FILE_DISABLED);
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "indirectc.service", &state) >= 0 && state == UNIT_FILE_INDIRECT);
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "indirectc.service", &state) >= 0 && state == UNIT_FILE_ALIAS);
assert_se(unit_file_enable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("indirectc.service"), &changes, &n_changes) >= 0);
assert_se(n_changes == 1);
@ -513,7 +513,7 @@ static void test_indirect(const char *root) {
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "indirecta.service", &state) >= 0 && state == UNIT_FILE_INDIRECT);
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "indirectb.service", &state) >= 0 && state == UNIT_FILE_ENABLED);
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "indirectc.service", &state) >= 0 && state == UNIT_FILE_INDIRECT);
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "indirectc.service", &state) >= 0 && state == UNIT_FILE_ALIAS);
assert_se(unit_file_disable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("indirectc.service"), &changes, &n_changes) >= 0);
assert_se(n_changes == 1);
@ -624,7 +624,7 @@ static void test_preset_and_list(const char *root) {
got_no = true;
assert_se(fl->state == UNIT_FILE_DISABLED);
} else
assert_se(IN_SET(fl->state, UNIT_FILE_DISABLED, UNIT_FILE_STATIC, UNIT_FILE_INDIRECT));
assert_se(IN_SET(fl->state, UNIT_FILE_DISABLED, UNIT_FILE_STATIC, UNIT_FILE_INDIRECT, UNIT_FILE_ALIAS));
}
unit_file_list_free(h);