]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
Merge pull request #20988 from DaanDeMeyer/rotate-reason
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Tue, 19 Oct 2021 07:53:31 +0000 (09:53 +0200)
committerGitHub <noreply@github.com>
Tue, 19 Oct 2021 07:53:31 +0000 (09:53 +0200)
journal: Improve rotation logging

1037 files changed:
.gitattributes
.github/workflows/build_test.sh
.gitignore
LICENSES/OFL-1.1.txt [new file with mode: 0644]
LICENSES/README.md
TODO
coccinelle/strdupa.cocci [new file with mode: 0644]
docs/.gitattributes [new file with mode: 0644]
docs/CODING_STYLE.md
docs/CONTRIBUTING.md
docs/ENVIRONMENT.md
docs/HACKING.md
docs/_config.yml
docs/_includes/footer.html
docs/_includes/head.html
docs/_includes/header.html
docs/_layouts/default.html
docs/assets/page-logo.svg
docs/favicon.svg
docs/style.css
hwdb.d/acpi-update.py
hwdb.d/ids_parser.py
man/bootctl.xml
man/crypttab.xml
man/homectl.xml
man/integritytab.xml [new file with mode: 0644]
man/kernel-command-line.xml
man/loader.conf.xml
man/rules/meson.build
man/systemd-integritysetup-generator.xml [new file with mode: 0644]
man/systemd-integritysetup@.service.xml [new file with mode: 0644]
man/systemd-machine-id-setup.xml
man/systemd-stub.xml
man/systemd-system.conf.xml
man/systemd-veritysetup-generator.xml
man/systemd-veritysetup@.service.xml
man/systemd.network.xml
man/systemd.special.xml
man/veritytab.xml
meson.build
mkosi.default.d/arch/10-mkosi.arch [moved from mkosi.default.d/arch/mkosi.arch with 100% similarity]
mkosi.default.d/debian/10-mkosi.debian [moved from mkosi.default.d/debian/mkosi.debian with 100% similarity]
mkosi.default.d/fedora/10-mkosi.fedora [moved from mkosi.default.d/fedora/mkosi.fedora with 100% similarity]
mkosi.default.d/opensuse/10-mkosi.opensuse [moved from mkosi.default.d/opensuse/mkosi.opensuse with 100% similarity]
mkosi.default.d/ubuntu/10-mkosi.ubuntu [moved from mkosi.default.d/ubuntu/mkosi.ubuntu with 100% similarity]
po/.gitattributes [new file with mode: 0644]
po/POTFILES.skip
shell-completion/bash/bootctl
shell-completion/zsh/_bootctl
src/backlight/backlight.c
src/basic/alloc-util.h
src/basic/cgroup-util.c
src/basic/env-util.c
src/basic/fileio.c
src/basic/fileio.h
src/basic/fs-util.c
src/basic/log.c
src/basic/macro.h
src/basic/missing_syscall.h
src/basic/mkdir.c
src/basic/mountpoint-util.c
src/basic/parse-util.c
src/basic/path-lookup.c
src/basic/percent-util.c
src/basic/procfs-util.c
src/basic/recurse-dir.c
src/basic/recurse-dir.h
src/basic/signal-util.c
src/basic/socket-util.c
src/basic/socket-util.h
src/basic/sort-util.c
src/basic/sort-util.h
src/basic/sparse-endian.h
src/basic/time-util.c
src/basic/user-util.c
src/basic/user-util.h
src/basic/util.c
src/basic/virt.c
src/boot/bless-boot.c
src/boot/bootctl.c
src/boot/efi/boot.c
src/boot/efi/cpio.c
src/boot/efi/devicetree.c
src/boot/efi/devicetree.h
src/boot/efi/disk.c
src/boot/efi/graphics.c
src/boot/efi/initrd.c [new file with mode: 0644]
src/boot/efi/initrd.h [new file with mode: 0644]
src/boot/efi/linux.c
src/boot/efi/linux.h
src/boot/efi/linux_x86.c [new file with mode: 0644]
src/boot/efi/meson.build
src/boot/efi/missing_efi.h
src/boot/efi/pe.c
src/boot/efi/pe.h
src/boot/efi/shim.c
src/boot/efi/stub.c
src/boot/efi/xbootldr.c [new file with mode: 0644]
src/boot/efi/xbootldr.h [new file with mode: 0644]
src/busctl/test-busctl-introspect.c
src/core/automount.c
src/core/bpf-devices.c
src/core/bpf-devices.h
src/core/bpf-firewall.c
src/core/bpf-foreign.c
src/core/bpf/restrict_fs/meson.build
src/core/cgroup.c
src/core/dbus-execute.c
src/core/dbus-util.c
src/core/execute.c
src/core/load-fragment.c
src/core/load-fragment.h
src/core/main.c
src/core/manager.c
src/core/selinux-access.c
src/core/system.conf.in
src/core/unit-serialize.c
src/core/unit.c
src/coredump/coredump-vacuum.c
src/coredump/coredumpctl.c
src/cryptsetup/cryptsetup-fido2.c
src/cryptsetup/cryptsetup.c
src/fundamental/macro-fundamental.h
src/fuzz/fuzz-fido-id-desc.dict [deleted file]
src/home/homectl.c
src/home/homed-home.c
src/home/homed-home.h
src/home/homed-manager.c
src/home/homework-cifs.c
src/home/homework-cifs.h
src/home/homework-directory.c
src/home/homework-directory.h
src/home/homework-fscrypt.c
src/home/homework-fscrypt.h
src/home/homework-luks.c
src/home/homework-luks.h
src/home/homework.c
src/home/homework.h
src/home/user-record-util.c
src/integritysetup/integrity-util.c [new file with mode: 0644]
src/integritysetup/integrity-util.h [new file with mode: 0644]
src/integritysetup/integritysetup-generator.c [new file with mode: 0644]
src/integritysetup/integritysetup.c [new file with mode: 0644]
src/journal-remote/journal-remote-main.c
src/journal-remote/journal-upload.c
src/journal/journalctl.c
src/journal/journald-stream.c
src/libsystemd-network/dhcp-identifier.c
src/libsystemd-network/dhcp6-internal.h
src/libsystemd-network/dhcp6-option.c
src/libsystemd-network/dhcp6-protocol.h
src/libsystemd-network/sd-dhcp6-client.c
src/libsystemd-network/sd-radv.c
src/libsystemd-network/test-dhcp-client.c
src/libsystemd-network/test-dhcp-option.c
src/libsystemd-network/test-dhcp6-client.c
src/libsystemd-network/test-ipv4ll.c
src/libsystemd-network/test-ndisc-ra.c
src/libsystemd-network/test-ndisc-rs.c
src/libsystemd/sd-bus/bus-common-errors.c
src/libsystemd/sd-bus/bus-common-errors.h
src/libsystemd/sd-bus/bus-message.c
src/libsystemd/sd-bus/bus-objects.c
src/libsystemd/sd-bus/bus-socket.c
src/libsystemd/sd-bus/sd-bus.c
src/libsystemd/sd-bus/test-bus-address.c
src/libsystemd/sd-bus/test-bus-objects.c
src/libsystemd/sd-device/device-monitor.c
src/libsystemd/sd-device/sd-device.c
src/libsystemd/sd-event/test-event.c
src/libsystemd/sd-journal/journal-authenticate.c
src/libsystemd/sd-journal/journal-file.c
src/libsystemd/sd-journal/journal-send.c
src/libsystemd/sd-journal/sd-journal.c
src/libsystemd/sd-journal/test-compress.c
src/libsystemd/sd-login/sd-login.c
src/libsystemd/sd-netlink/netlink-socket.c
src/libsystemd/sd-netlink/test-netlink.c
src/locale/keymap-util.c
src/locale/localed.c
src/machine/machine-dbus.c
src/network/generator/network-generator.c
src/network/networkd-dhcp6.c
src/network/networkd-link.c
src/network/networkd-manager.c
src/network/networkd-manager.h
src/network/networkd-neighbor.c
src/network/networkd-network-gperf.gperf
src/network/networkd-network.c
src/network/networkd-network.h
src/network/networkd-radv.c
src/network/networkd-radv.h
src/network/test-network-tables.c
src/nspawn/nspawn-expose-ports.c
src/nspawn/nspawn-settings.c
src/oom/test-oomd-util.c
src/portable/portable.c
src/resolve/resolvectl.c
src/resolve/test-resolved-etc-hosts.c
src/shared/bpf-program.c
src/shared/bpf-program.h
src/shared/bus-get-properties.c
src/shared/bus-unit-procs.c
src/shared/bus-unit-util.c
src/shared/cgroup-setup.c
src/shared/dissect-image.c
src/shared/dns-domain.c
src/shared/ethtool-util.c
src/shared/firewall-util-iptables.c
src/shared/journal-importer.c
src/shared/libfido2-util.c
src/shared/libfido2-util.h
src/shared/logs-show.c
src/shared/nscd-flush.c
src/shared/pager.c
src/shared/rm-rf.c
src/shared/rm-rf.h
src/shared/selinux-util.c
src/shared/tpm2-util.c
src/shared/uid-range.c
src/shared/user-record-show.c
src/shared/user-record.c
src/shared/user-record.h
src/shared/varlink.c
src/shared/watchdog.c
src/shutdown/umount.c
src/socket-proxy/socket-proxyd.c
src/systemd/sd-dhcp6-client.h
src/systemd/sd-radv.h
src/sysv-generator/sysv-generator.c
src/test/test-boot-timestamps.c
src/test/test-bpf-devices.c
src/test/test-bpf-firewall.c
src/test/test-bpf-foreign-programs.c
src/test/test-bus-util.c
src/test/test-calendarspec.c
src/test/test-capability.c
src/test/test-cgroup-util.c
src/test/test-chase-symlinks.c
src/test/test-condition.c
src/test/test-cpu-set-util.c
src/test/test-escape.c
src/test/test-exec-util.c
src/test/test-execute.c
src/test/test-fileio.c
src/test/test-firewall-util.c
src/test/test-hashmap-plain.c
src/test/test-hexdecoct.c
src/test/test-hostname-setup.c
src/test/test-hostname-util.c
src/test/test-install-root.c
src/test/test-log.c
src/test/test-macro.c
src/test/test-modhex.c
src/test/test-path-lookup.c
src/test/test-path-util.c
src/test/test-psi-util.c
src/test/test-recurse-dir.c
src/test/test-sd-hwdb.c
src/test/test-set.c
src/test/test-signal-util.c
src/test/test-socket-netlink.c
src/test/test-socket-util.c
src/test/test-stat-util.c
src/test/test-string-util.c
src/test/test-strv.c
src/test/test-time-util.c
src/test/test-tmpfile-util.c
src/test/test-unit-file.c
src/test/test-unit-serialize.c
src/test/test-user-util.c
src/test/test-varlink.c
src/timedate/timedatectl.c
src/tmpfiles/test-offline-passwd.c
src/udev/dmi_memory_id/dmi_memory_id.c
src/udev/scsi_id/scsi_serial.c
src/udev/udev-builtin-path_id.c
src/udev/udev-event.c
src/userdb/userdbctl.c
src/veritysetup/veritysetup-generator.c
src/veritysetup/veritysetup.c
test/TEST-01-BASIC/Makefile
test/TEST-01-BASIC/test.sh
test/TEST-02-UNITTESTS/test.sh
test/TEST-03-JOBS/test.sh
test/TEST-04-JOURNAL/test.sh
test/TEST-05-RLIMITS/test.sh
test/TEST-06-SELINUX/systemd_test.fc
test/TEST-06-SELINUX/systemd_test.if
test/TEST-06-SELINUX/systemd_test.te
test/TEST-06-SELINUX/test.sh
test/TEST-07-ISSUE-1981/test.sh
test/TEST-08-ISSUE-2730/test.sh
test/TEST-09-ISSUE-2691/test.sh
test/TEST-10-ISSUE-2467/test.sh
test/TEST-11-ISSUE-3166/test.sh
test/TEST-12-ISSUE-3171/test.sh
test/TEST-13-NSPAWN-SMOKE/test.sh
test/TEST-14-MACHINE-ID/test.sh
test/TEST-15-DROPIN/test.sh
test/TEST-16-EXTEND-TIMEOUT/test.sh
test/TEST-17-UDEV/test.sh
test/TEST-18-FAILUREACTION/test.sh
test/TEST-19-DELEGATE/test.sh
test/TEST-20-MAINPIDGAMES/test.sh
test/TEST-22-TMPFILES/test.sh
test/TEST-23-TYPE-EXEC/test.sh
test/TEST-24-CRYPTSETUP/test.sh
test/TEST-25-IMPORT/test.sh
test/TEST-26-SETENV/test.sh
test/TEST-27-STDOUTFILE/test.sh
test/TEST-28-PERCENTJ-WANTEDBY/test.sh
test/TEST-29-PORTABLE/test.sh
test/TEST-30-ONCLOCKCHANGE/test.sh
test/TEST-31-DEVICE-ENUMERATION/test.sh
test/TEST-32-OOMPOLICY/test.sh
test/TEST-33-CLEAN-UNIT/test.sh
test/TEST-34-DYNAMICUSERMIGRATE/test.sh
test/TEST-36-NUMAPOLICY/test.sh
test/TEST-37-RUNTIMEDIRECTORYPRESERVE/test.sh
test/TEST-38-FREEZER/test.sh
test/TEST-39-EXECRELOAD/test.sh
test/TEST-40-EXEC-COMMAND-EX/test.sh
test/TEST-41-ONESHOT-RESTART/test.sh
test/TEST-42-EXECSTOPPOST/test.sh
test/TEST-43-PRIVATEUSER-UNPRIV/test.sh
test/TEST-44-LOG-NAMESPACE/test.sh
test/TEST-46-HOMED/test.sh
test/TEST-47-ISSUE-14566/test.sh
test/TEST-48-START-STOP-NO-RELOAD/test.sh
test/TEST-49-RUNTIME-BIND-PATHS/test.sh
test/TEST-50-DISSECT/test.sh
test/TEST-51-ISSUE-16115/test.sh
test/TEST-52-HONORFIRSTSHUTDOWN/test.sh
test/TEST-53-ISSUE-16347/test.sh
test/TEST-54-CREDS/test.sh
test/TEST-55-OOMD/test.sh
test/TEST-57-ONSUCCESS-UPHOLD/test.sh
test/TEST-58-REPART/test.sh
test/TEST-59-RELOADING-RESTART/test.sh
test/TEST-60-MOUNT-RATELIMIT/test.sh
test/TEST-61-UNITTESTS-QEMU/test.sh
test/TEST-62-RESTRICT-IFACES/test.sh
test/TEST-63-ISSUE-17433/test.sh
test/TEST-64-UDEV-STORAGE/test.sh
test/TEST-65-ANALYZE/test.sh
test/TEST-66-DEVICE-ISOLATION/Makefile [new symlink]
test/TEST-66-DEVICE-ISOLATION/test.sh [new file with mode: 0755]
test/dmidecode-dumps/.gitattributes [new file with mode: 0644]
test/fuzz/.gitattributes
test/journal-data/.gitattributes [new file with mode: 0644]
test/test-execute/exec-ambientcapabilities-merge-nfsnobody.service
test/test-execute/exec-ambientcapabilities-merge-nobody.service
test/test-execute/exec-ambientcapabilities-merge.service
test/test-execute/exec-ambientcapabilities-nfsnobody.service
test/test-execute/exec-ambientcapabilities-nobody.service
test/test-execute/exec-ambientcapabilities.service
test/test-execute/exec-basic.service
test/test-execute/exec-bindpaths.service
test/test-execute/exec-capabilityboundingset-invert.service
test/test-execute/exec-capabilityboundingset-merge.service
test/test-execute/exec-capabilityboundingset-reset.service
test/test-execute/exec-capabilityboundingset-simple.service
test/test-execute/exec-condition-failed.service
test/test-execute/exec-condition-skip.service
test/test-execute/exec-cpuaffinity1.service
test/test-execute/exec-cpuaffinity2.service
test/test-execute/exec-cpuaffinity3.service
test/test-execute/exec-dynamicuser-fixeduser-adm.service
test/test-execute/exec-dynamicuser-fixeduser-games.service
test/test-execute/exec-dynamicuser-fixeduser-one-supplementarygroup.service
test/test-execute/exec-dynamicuser-fixeduser.service
test/test-execute/exec-dynamicuser-runtimedirectory1.service
test/test-execute/exec-dynamicuser-runtimedirectory2.service
test/test-execute/exec-dynamicuser-runtimedirectory3.service
test/test-execute/exec-dynamicuser-statedir-migrate-step1.service
test/test-execute/exec-dynamicuser-statedir-migrate-step2.service
test/test-execute/exec-dynamicuser-statedir.service
test/test-execute/exec-dynamicuser-supplementarygroups.service
test/test-execute/exec-environment-empty.service
test/test-execute/exec-environment-multiple.service
test/test-execute/exec-environment-no-substitute.service
test/test-execute/exec-environment.service
test/test-execute/exec-environmentfile.service
test/test-execute/exec-execsearchpath-environment-path-set.service
test/test-execute/exec-execsearchpath-environment.service
test/test-execute/exec-execsearchpath-environmentfile-set.service
test/test-execute/exec-execsearchpath-environmentfile.service
test/test-execute/exec-execsearchpath-passenvironment-set.service
test/test-execute/exec-execsearchpath-passenvironment.service
test/test-execute/exec-execsearchpath-unit-specifier.service
test/test-execute/exec-execsearchpath.service
test/test-execute/exec-group-nfsnobody.service
test/test-execute/exec-group-nobody.service
test/test-execute/exec-group-nogroup.service
test/test-execute/exec-group.service
test/test-execute/exec-ignoresigpipe-no.service
test/test-execute/exec-ignoresigpipe-yes.service
test/test-execute/exec-inaccessiblepaths-mount-propagation.service
test/test-execute/exec-inaccessiblepaths-sys.service
test/test-execute/exec-ioschedulingclass-best-effort.service
test/test-execute/exec-ioschedulingclass-idle.service
test/test-execute/exec-ioschedulingclass-none.service
test/test-execute/exec-ioschedulingclass-realtime.service
test/test-execute/exec-mount-apivfs-no.service
test/test-execute/exec-noexecpaths-simple.service
test/test-execute/exec-oomscoreadjust-negative.service
test/test-execute/exec-oomscoreadjust-positive.service
test/test-execute/exec-passenvironment-absent.service
test/test-execute/exec-passenvironment-empty.service
test/test-execute/exec-passenvironment-repeated.service
test/test-execute/exec-passenvironment.service
test/test-execute/exec-personality-aarch64.service
test/test-execute/exec-personality-ppc64.service
test/test-execute/exec-personality-ppc64le.service
test/test-execute/exec-personality-s390.service
test/test-execute/exec-personality-x86-64.service
test/test-execute/exec-personality-x86.service
test/test-execute/exec-privatedevices-disabled-by-prefix.service
test/test-execute/exec-privatedevices-no-capability-mknod.service
test/test-execute/exec-privatedevices-no-capability-sys-rawio.service
test/test-execute/exec-privatedevices-no.service
test/test-execute/exec-privatedevices-yes-capability-mknod.service
test/test-execute/exec-privatedevices-yes-capability-sys-rawio.service
test/test-execute/exec-privatedevices-yes-with-group.service
test/test-execute/exec-privatedevices-yes.service
test/test-execute/exec-privatenetwork-yes.service
test/test-execute/exec-privatetmp-disabled-by-prefix.service
test/test-execute/exec-privatetmp-no.service
test/test-execute/exec-privatetmp-yes.service
test/test-execute/exec-protecthome-tmpfs-vs-protectsystem-strict.service
test/test-execute/exec-protectkernellogs-no-capabilities.service
test/test-execute/exec-protectkernellogs-yes-capabilities.service
test/test-execute/exec-protectkernelmodules-no-capabilities.service
test/test-execute/exec-protectkernelmodules-yes-capabilities.service
test/test-execute/exec-protectkernelmodules-yes-mount-propagation.service
test/test-execute/exec-readonlypaths-mount-propagation.service
test/test-execute/exec-readonlypaths-simple.service
test/test-execute/exec-readonlypaths-with-bindpaths.service
test/test-execute/exec-readonlypaths.service
test/test-execute/exec-readwritepaths-mount-propagation.service
test/test-execute/exec-restrictnamespaces-merge-all.service
test/test-execute/exec-restrictnamespaces-merge-and.service
test/test-execute/exec-restrictnamespaces-merge-or.service
test/test-execute/exec-restrictnamespaces-mnt-deny-list.service
test/test-execute/exec-restrictnamespaces-mnt.service
test/test-execute/exec-restrictnamespaces-no.service
test/test-execute/exec-restrictnamespaces-yes.service
test/test-execute/exec-runtimedirectory-mode.service
test/test-execute/exec-runtimedirectory-owner-nfsnobody.service
test/test-execute/exec-runtimedirectory-owner-nobody.service
test/test-execute/exec-runtimedirectory-owner-nogroup.service
test/test-execute/exec-runtimedirectory-owner.service
test/test-execute/exec-runtimedirectory.service
test/test-execute/exec-specifier-interpolation.service
test/test-execute/exec-specifier.service
test/test-execute/exec-specifier@.service
test/test-execute/exec-standardinput-data.service
test/test-execute/exec-standardinput-file-cat.service
test/test-execute/exec-standardinput-file.service
test/test-execute/exec-standardoutput-append.service
test/test-execute/exec-standardoutput-file.service
test/test-execute/exec-standardoutput-truncate.service
test/test-execute/exec-supplementarygroups-multiple-groups-default-group-user.service
test/test-execute/exec-supplementarygroups-multiple-groups-withgid.service
test/test-execute/exec-supplementarygroups-multiple-groups-withuid.service
test/test-execute/exec-supplementarygroups-single-group-user.service
test/test-execute/exec-supplementarygroups-single-group.service
test/test-execute/exec-supplementarygroups.service
test/test-execute/exec-systemcallerrornumber-name.service
test/test-execute/exec-systemcallerrornumber-number.service
test/test-execute/exec-systemcallfilter-failing.service
test/test-execute/exec-systemcallfilter-failing2.service
test/test-execute/exec-systemcallfilter-failing3.service
test/test-execute/exec-systemcallfilter-not-failing.service
test/test-execute/exec-systemcallfilter-not-failing2.service
test/test-execute/exec-systemcallfilter-not-failing3.service
test/test-execute/exec-systemcallfilter-override-error-action.service
test/test-execute/exec-systemcallfilter-override-error-action2.service
test/test-execute/exec-systemcallfilter-system-user-nfsnobody.service
test/test-execute/exec-systemcallfilter-system-user-nobody.service
test/test-execute/exec-systemcallfilter-system-user.service
test/test-execute/exec-systemcallfilter-with-errno-in-allow-list.service
test/test-execute/exec-systemcallfilter-with-errno-multi.service
test/test-execute/exec-systemcallfilter-with-errno-name.service
test/test-execute/exec-systemcallfilter-with-errno-number.service
test/test-execute/exec-temporaryfilesystem-options.service
test/test-execute/exec-temporaryfilesystem-ro.service
test/test-execute/exec-temporaryfilesystem-rw.service
test/test-execute/exec-temporaryfilesystem-usr.service
test/test-execute/exec-umask-0177.service
test/test-execute/exec-umask-default.service
test/test-execute/exec-unsetenvironment.service
test/test-execute/exec-user-nfsnobody.service
test/test-execute/exec-user-nobody.service
test/test-execute/exec-user.service
test/test-execute/exec-workingdirectory-trailing-dot.service
test/test-execute/exec-workingdirectory.service
test/test-network-generator-conversion/.gitattributes [new file with mode: 0644]
test/test-network/.gitattributes [new file with mode: 0644]
test/test-network/conf/10-dropin-test.netdev
test/test-network/conf/11-dummy-mtu.netdev
test/test-network/conf/11-dummy.netdev
test/test-network/conf/11-dummy.network
test/test-network/conf/12-dummy-mtu.link
test/test-network/conf/12-dummy-mtu.netdev
test/test-network/conf/12-dummy.link
test/test-network/conf/12-dummy.netdev
test/test-network/conf/12-dummy.network
test/test-network/conf/13-not-match-udev-property.network
test/test-network/conf/14-match-udev-property.network
test/test-network/conf/15-name-conflict-test.netdev
test/test-network/conf/21-macvlan.netdev
test/test-network/conf/21-macvtap.netdev
test/test-network/conf/21-vlan-test1.network
test/test-network/conf/21-vlan.netdev
test/test-network/conf/21-vlan.network
test/test-network/conf/23-active-slave.network
test/test-network/conf/23-bond199.network
test/test-network/conf/23-emit-lldp.network
test/test-network/conf/23-keep-master.network
test/test-network/conf/23-primary-slave.network
test/test-network/conf/24-keep-configuration-static.network
test/test-network/conf/24-lldp.network
test/test-network/conf/24-search-domain.network
test/test-network/conf/25-6rd-tunnel.netdev
test/test-network/conf/25-activation-policy.network
test/test-network/conf/25-address-ipv4acd-veth99.network
test/test-network/conf/25-address-link-section.network
test/test-network/conf/25-address-peer-ipv4.network
test/test-network/conf/25-address-static.network
test/test-network/conf/25-bareudp.netdev
test/test-network/conf/25-batadv.netdev
test/test-network/conf/25-bind-carrier.network
test/test-network/conf/25-bond-active-backup-slave.netdev
test/test-network/conf/25-bond-balanced-tlb.netdev
test/test-network/conf/25-bond.netdev
test/test-network/conf/25-bridge-configure-without-carrier.network
test/test-network/conf/25-bridge.netdev
test/test-network/conf/25-bridge.network
test/test-network/conf/25-erspan-tunnel-local-any.netdev
test/test-network/conf/25-erspan-tunnel.netdev
test/test-network/conf/25-fibrule-invert.network
test/test-network/conf/25-fibrule-port-range.network
test/test-network/conf/25-fibrule-uidrange.network
test/test-network/conf/25-fou-gre.netdev
test/test-network/conf/25-fou-gretap.netdev
test/test-network/conf/25-fou-ipip.netdev
test/test-network/conf/25-fou-ipproto-gre.netdev
test/test-network/conf/25-fou-ipproto-ipip.netdev
test/test-network/conf/25-fou-sit.netdev
test/test-network/conf/25-gateway-next-static.network
test/test-network/conf/25-gateway-static.network
test/test-network/conf/25-geneve.netdev
test/test-network/conf/25-gre-tunnel-any-any.netdev
test/test-network/conf/25-gre-tunnel-local-any.netdev
test/test-network/conf/25-gre-tunnel-remote-any.netdev
test/test-network/conf/25-gre-tunnel.netdev
test/test-network/conf/25-gretap-tunnel-local-any.netdev
test/test-network/conf/25-gretap-tunnel.netdev
test/test-network/conf/25-ifb.netdev
test/test-network/conf/25-ip6gre-tunnel-any-any.netdev
test/test-network/conf/25-ip6gre-tunnel-local-any.netdev
test/test-network/conf/25-ip6gre-tunnel-remote-any.netdev
test/test-network/conf/25-ip6gre-tunnel.netdev
test/test-network/conf/25-ip6gretap-tunnel-local-any.netdev
test/test-network/conf/25-ip6gretap-tunnel.netdev
test/test-network/conf/25-ip6tnl-tunnel-local-any.netdev
test/test-network/conf/25-ip6tnl-tunnel-remote-any.netdev
test/test-network/conf/25-ip6tnl-tunnel.netdev
test/test-network/conf/25-ipip-tunnel-any-any.netdev
test/test-network/conf/25-ipip-tunnel-independent-loopback.netdev
test/test-network/conf/25-ipip-tunnel-independent.netdev
test/test-network/conf/25-ipip-tunnel-local-any.netdev
test/test-network/conf/25-ipip-tunnel-remote-any.netdev
test/test-network/conf/25-ipip-tunnel.netdev
test/test-network/conf/25-ipv6-address-label-section.network
test/test-network/conf/25-ipv6-proxy-ndp.network
test/test-network/conf/25-ipvlan.netdev
test/test-network/conf/25-ipvtap.netdev
test/test-network/conf/25-isatap-tunnel.netdev
test/test-network/conf/25-l2tp-dummy.network
test/test-network/conf/25-l2tp-ip.netdev
test/test-network/conf/25-l2tp-udp.netdev
test/test-network/conf/25-l2tp.network
test/test-network/conf/25-link-local-addressing-no.network
test/test-network/conf/25-link-local-addressing-yes.network
test/test-network/conf/25-link-section-unmanaged.network
test/test-network/conf/25-macsec.netdev
test/test-network/conf/25-macsec.network
test/test-network/conf/25-neighbor-ip-dummy.network
test/test-network/conf/25-neighbor-ip.network
test/test-network/conf/25-neighbor-ipv6.network
test/test-network/conf/25-neighbor-next.network
test/test-network/conf/25-neighbor-section.network
test/test-network/conf/25-nexthop-dummy.network
test/test-network/conf/25-nexthop-nothing.network
test/test-network/conf/25-nexthop.network
test/test-network/conf/25-nlmon.netdev
test/test-network/conf/25-prefix-route-with-vrf.network
test/test-network/conf/25-prefix-route-without-vrf.network
test/test-network/conf/25-qdisc-cake.network
test/test-network/conf/25-qdisc-clsact-and-htb.network
test/test-network/conf/25-qdisc-drr.network
test/test-network/conf/25-qdisc-ets.network
test/test-network/conf/25-qdisc-fq_pie.network
test/test-network/conf/25-qdisc-hhf.network
test/test-network/conf/25-qdisc-ingress-netem-compat.network
test/test-network/conf/25-qdisc-pie.network
test/test-network/conf/25-qdisc-qfq.network
test/test-network/conf/25-route-ipv6-src.network
test/test-network/conf/25-route-static.network
test/test-network/conf/25-route-via-ipv6.network
test/test-network/conf/25-route-vrf.network
test/test-network/conf/25-sit-tunnel-any-any.netdev
test/test-network/conf/25-sit-tunnel-local-any.netdev
test/test-network/conf/25-sit-tunnel-remote-any.netdev
test/test-network/conf/25-sit-tunnel.netdev
test/test-network/conf/25-sriov.network
test/test-network/conf/25-sysctl-disable-ipv6.network
test/test-network/conf/25-sysctl.network
test/test-network/conf/25-tap.netdev
test/test-network/conf/25-test1.network
test/test-network/conf/25-tun.netdev
test/test-network/conf/25-tunnel-any-any.network
test/test-network/conf/25-tunnel-local-any.network
test/test-network/conf/25-tunnel-remote-any.network
test/test-network/conf/25-tunnel.network
test/test-network/conf/25-vcan.netdev
test/test-network/conf/25-veth-peer.network
test/test-network/conf/25-veth.netdev
test/test-network/conf/25-vrf.netdev
test/test-network/conf/25-vrf.network
test/test-network/conf/25-vti-tunnel-any-any.netdev
test/test-network/conf/25-vti-tunnel-local-any.netdev
test/test-network/conf/25-vti-tunnel-remote-any.netdev
test/test-network/conf/25-vti-tunnel.netdev
test/test-network/conf/25-vti6-tunnel-local-any.netdev
test/test-network/conf/25-vti6-tunnel-remote-any.netdev
test/test-network/conf/25-vti6-tunnel.netdev
test/test-network/conf/25-vxcan.netdev
test/test-network/conf/25-vxlan-independent.netdev
test/test-network/conf/25-vxlan-ipv6.netdev
test/test-network/conf/25-vxlan.netdev
test/test-network/conf/25-wireguard-23-peers.netdev
test/test-network/conf/25-wireguard-23-peers.network
test/test-network/conf/25-wireguard-no-peer.netdev
test/test-network/conf/25-wireguard-no-peer.network
test/test-network/conf/25-wireguard.netdev
test/test-network/conf/25-wireguard.network
test/test-network/conf/25-xfrm-independent.netdev
test/test-network/conf/25-xfrm.netdev
test/test-network/conf/26-bridge-configure-without-carrier.network
test/test-network/conf/26-bridge-issue-20373.netdev
test/test-network/conf/26-bridge-mdb-master.network
test/test-network/conf/26-bridge-mdb-slave.network
test/test-network/conf/26-bridge-slave-interface-1.network
test/test-network/conf/26-bridge-slave-interface-2.network
test/test-network/conf/26-bridge-vlan-master-issue-20373.network
test/test-network/conf/26-bridge-vlan-master.network
test/test-network/conf/26-bridge-vlan-slave-issue-20373.network
test/test-network/conf/26-bridge-vlan-slave.network
test/test-network/conf/26-bridge.netdev
test/test-network/conf/26-link-local-addressing-ipv6.network
test/test-network/conf/6rd.network
test/test-network/conf/agent-client-peer.network
test/test-network/conf/agent-client.network
test/test-network/conf/agent-server-peer.network
test/test-network/conf/agent-server.network
test/test-network/conf/agent-veth-client.netdev
test/test-network/conf/agent-veth-server.netdev
test/test-network/conf/bond-slave.network
test/test-network/conf/bond99.network
test/test-network/conf/bridge99-ignore-carrier-loss.network
test/test-network/conf/bridge99.network
test/test-network/conf/dhcp-client-allow-list.network
test/test-network/conf/dhcp-client-anonymize.network
test/test-network/conf/dhcp-client-decline.network
test/test-network/conf/dhcp-client-gateway-ipv4.network
test/test-network/conf/dhcp-client-gateway-ipv6.network
test/test-network/conf/dhcp-client-gateway-onlink-implicit.network
test/test-network/conf/dhcp-client-ipv4-dhcp-settings.network
test/test-network/conf/dhcp-client-ipv4-ipv6ra-prefix-client-with-delay.network
test/test-network/conf/dhcp-client-ipv4-only-ipv6-disabled.network
test/test-network/conf/dhcp-client-ipv4-only.network
test/test-network/conf/dhcp-client-ipv4-use-routes-use-gateway.network
test/test-network/conf/dhcp-client-ipv6-only.network
test/test-network/conf/dhcp-client-ipv6-rapid-commit.network [deleted file]
test/test-network/conf/dhcp-client-keep-configuration-dhcp-on-stop.network
test/test-network/conf/dhcp-client-keep-configuration-dhcp.network
test/test-network/conf/dhcp-client-listen-port.network
test/test-network/conf/dhcp-client-reassign-static-routes-ipv4.network
test/test-network/conf/dhcp-client-reassign-static-routes-ipv6.network
test/test-network/conf/dhcp-client-route-metric.network
test/test-network/conf/dhcp-client-route-table.network
test/test-network/conf/dhcp-client-static-lease.network
test/test-network/conf/dhcp-client-timezone-router.network
test/test-network/conf/dhcp-client-use-dns-ipv4-and-ra.network
test/test-network/conf/dhcp-client-use-dns-ipv4.network
test/test-network/conf/dhcp-client-use-dns-no.network
test/test-network/conf/dhcp-client-use-dns-yes.network
test/test-network/conf/dhcp-client-use-domains.network
test/test-network/conf/dhcp-client-vrf.network
test/test-network/conf/dhcp-client-with-ipv4ll.network
test/test-network/conf/dhcp-client-with-static-address.network
test/test-network/conf/dhcp-client.network
test/test-network/conf/dhcp-server-decline.network
test/test-network/conf/dhcp-server-static-lease.network
test/test-network/conf/dhcp-server-timezone-router.network
test/test-network/conf/dhcp-server-uplink.network
test/test-network/conf/dhcp-server-veth-peer.network
test/test-network/conf/dhcp-server-with-ipv6-prefix.network
test/test-network/conf/dhcp-server.network
test/test-network/conf/dhcp-v4-server-veth-peer.network
test/test-network/conf/erspan.network
test/test-network/conf/gretap.network
test/test-network/conf/gretun.network
test/test-network/conf/ip6gretap.network
test/test-network/conf/ip6gretun.network
test/test-network/conf/ip6tnl.network
test/test-network/conf/ipip.network
test/test-network/conf/ipv6-prefix-veth-token-prefixstable-without-address.network
test/test-network/conf/ipv6-prefix-veth-token-prefixstable.network
test/test-network/conf/ipv6-prefix-veth-token-static.network
test/test-network/conf/ipv6-prefix-veth.network
test/test-network/conf/ipv6-prefix-with-delay.network
test/test-network/conf/ipv6-prefix.network
test/test-network/conf/ipv6ra-prefix-client-deny-list.network
test/test-network/conf/ipv6ra-prefix-client-with-static-ipv4-address.network
test/test-network/conf/ipv6ra-prefix-client.network
test/test-network/conf/ipv6ra-prefix.network
test/test-network/conf/ipv6ra-uplink.network
test/test-network/conf/ipvlan.network
test/test-network/conf/ipvtap.network
test/test-network/conf/isatap.network
test/test-network/conf/macsec.network
test/test-network/conf/macvlan.network
test/test-network/conf/macvtap.network
test/test-network/conf/netdev-link-local-addressing-yes.network
test/test-network/conf/networkd-manage-foreign-routes-no.conf
test/test-network/conf/routing-policy-rule-dummy98.network
test/test-network/conf/routing-policy-rule-reconfigure1.network
test/test-network/conf/routing-policy-rule-reconfigure2.network
test/test-network/conf/routing-policy-rule-test1.network
test/test-network/conf/sit.network
test/test-network/conf/state-file-tests.network
test/test-network/conf/vlan6.netdev
test/test-network/conf/vlan6.network
test/test-network/conf/vti.network
test/test-network/conf/vti6.network
test/test-network/conf/vxlan-ipv6.network
test/test-network/conf/vxlan-test1.network
test/test-network/conf/vxlan.network
test/test-network/conf/xfrm.network
test/test-network/systemd-networkd-tests.py
test/test-path-util/script.sh
test/test-path/basic.target
test/test-path/path-changed.path
test/test-path/path-changed.service
test/test-path/path-directorynotempty.path
test/test-path/path-directorynotempty.service
test/test-path/path-exists.path
test/test-path/path-exists.service
test/test-path/path-existsglob.path
test/test-path/path-existsglob.service
test/test-path/path-makedirectory.path
test/test-path/path-makedirectory.service
test/test-path/path-modified.path
test/test-path/path-modified.service
test/test-path/path-mycustomunit.service
test/test-path/path-unit.path
test/test-path/paths.target
test/test-path/sysinit.target
test/test-resolve/.gitattributes [new file with mode: 0644]
test/test-sysusers/.gitattributes [new file with mode: 0644]
test/test-sysusers/test-1.input
test/test-sysusers/test-10.input
test/test-sysusers/test-11.input
test/test-sysusers/test-12.input
test/test-sysusers/test-13.input
test/test-sysusers/test-14.input
test/test-sysusers/test-2.input
test/test-sysusers/test-3.input
test/test-sysusers/test-4.input
test/test-sysusers/test-5.input
test/test-sysusers/test-6.input
test/test-sysusers/test-7.input
test/test-sysusers/test-8.input
test/test-sysusers/test-9.input
test/test-sysusers/unhappy-1.input
test/test-sysusers/unhappy-2.input
test/test-sysusers/unhappy-3.input
test/test-umount/.gitattributes [new file with mode: 0644]
test/testsuite-04.units/forever-print-hola.service
test/testsuite-04.units/silent-success.service
test/testsuite-06.units/hola.service
test/testsuite-06.units/load-systemd-test-module.service
test/testsuite-08.units/-.mount
test/testsuite-08.units/systemd-remount-fs.service
test/testsuite-10.units/test10.service
test/testsuite-10.units/test10.socket
test/testsuite-11.units/fail-on-restart.service
test/testsuite-16.units/extend-timeout.sh
test/testsuite-16.units/fail-runtime.service
test/testsuite-16.units/fail-start.service
test/testsuite-16.units/fail-stop.service
test/testsuite-16.units/success-all.service
test/testsuite-16.units/success-runtime.service
test/testsuite-16.units/success-start.service
test/testsuite-16.units/success-stop.service
test/testsuite-28.units/specifier-j-depends-wants.service
test/testsuite-28.units/specifier-j-wants.service
test/testsuite-28.units/testsuite-28-pre.service
test/testsuite-30.units/systemd-timedated.service.d/watchdog.conf
test/testsuite-52.units/test-honor-first-shutdown.service
test/testsuite-52.units/test-honor-first-shutdown.sh
test/testsuite-63.units/test63.path
test/testsuite-63.units/test63.service
test/units/a-conj.service
test/units/a.service
test/units/autorelabel.service
test/units/b.service
test/units/c.service
test/units/d.service
test/units/daughter.service
test/units/dml-discard-empty.service
test/units/dml-discard-set-ml.service
test/units/dml-discard.slice
test/units/dml-override-empty.service
test/units/dml-override.slice
test/units/dml-passthrough-empty.service
test/units/dml-passthrough-set-dml.service
test/units/dml-passthrough-set-ml.service
test/units/dml-passthrough.slice
test/units/dml.slice
test/units/e.service
test/units/end.service
test/units/f.service
test/units/g.service
test/units/grandchild.service
test/units/h.service
test/units/hello-after-sleep.target
test/units/hello.service
test/units/i.service
test/units/loopy.service
test/units/loopy.service.d/compat.conf
test/units/loopy2.service
test/units/loopy3.service
test/units/loopy4.service
test/units/nomem.slice
test/units/nomemleaf.service
test/units/parent-deep.slice
test/units/parent.slice
test/units/sched_idle_bad.service
test/units/sched_idle_ok.service
test/units/sched_rr_bad.service
test/units/sched_rr_change.service
test/units/sched_rr_ok.service
test/units/sleep.service
test/units/son.service
test/units/testsuite-01.service
test/units/testsuite-02.service
test/units/testsuite-02.sh
test/units/testsuite-03.service
test/units/testsuite-03.sh
test/units/testsuite-04.service
test/units/testsuite-04.sh
test/units/testsuite-05.service
test/units/testsuite-05.sh
test/units/testsuite-06.service
test/units/testsuite-06.sh
test/units/testsuite-07.service
test/units/testsuite-07.sh
test/units/testsuite-08.service
test/units/testsuite-09.service
test/units/testsuite-10.service
test/units/testsuite-11.service
test/units/testsuite-11.sh
test/units/testsuite-12.service
test/units/testsuite-12.sh
test/units/testsuite-13.service
test/units/testsuite-13.sh
test/units/testsuite-14.service
test/units/testsuite-14.sh
test/units/testsuite-15.service
test/units/testsuite-15.sh
test/units/testsuite-16.service
test/units/testsuite-16.sh
test/units/testsuite-17.01.sh
test/units/testsuite-17.02.sh
test/units/testsuite-17.03.sh
test/units/testsuite-17.04.sh
test/units/testsuite-17.05.sh
test/units/testsuite-17.06.sh
test/units/testsuite-17.service
test/units/testsuite-17.sh
test/units/testsuite-18.service
test/units/testsuite-18.sh
test/units/testsuite-19.service
test/units/testsuite-19.sh
test/units/testsuite-20.service
test/units/testsuite-20.sh
test/units/testsuite-22.01.sh
test/units/testsuite-22.02.sh
test/units/testsuite-22.03.sh
test/units/testsuite-22.04.sh
test/units/testsuite-22.05.sh
test/units/testsuite-22.06.sh
test/units/testsuite-22.07.sh
test/units/testsuite-22.08.sh
test/units/testsuite-22.09.sh
test/units/testsuite-22.10.sh
test/units/testsuite-22.11.sh
test/units/testsuite-22.12.sh
test/units/testsuite-22.service
test/units/testsuite-22.sh
test/units/testsuite-23.service
test/units/testsuite-23.sh
test/units/testsuite-24.service
test/units/testsuite-25.service
test/units/testsuite-25.sh
test/units/testsuite-26.service
test/units/testsuite-26.sh
test/units/testsuite-27.service
test/units/testsuite-27.sh
test/units/testsuite-28.service
test/units/testsuite-29.service
test/units/testsuite-29.sh
test/units/testsuite-30.service
test/units/testsuite-30.sh
test/units/testsuite-31.service
test/units/testsuite-31.sh
test/units/testsuite-32.service
test/units/testsuite-32.sh
test/units/testsuite-33.service
test/units/testsuite-33.sh
test/units/testsuite-34.service
test/units/testsuite-34.sh
test/units/testsuite-36.service
test/units/testsuite-36.sh
test/units/testsuite-37.service
test/units/testsuite-37.sh
test/units/testsuite-38-sleep.service
test/units/testsuite-38.service
test/units/testsuite-38.sh
test/units/testsuite-39.service
test/units/testsuite-39.sh
test/units/testsuite-40.service
test/units/testsuite-40.sh
test/units/testsuite-41.service
test/units/testsuite-41.sh
test/units/testsuite-42.service
test/units/testsuite-42.sh
test/units/testsuite-43.service
test/units/testsuite-43.sh
test/units/testsuite-44.service
test/units/testsuite-44.sh
test/units/testsuite-46.service
test/units/testsuite-46.sh
test/units/testsuite-47-repro.service
test/units/testsuite-47-repro.sh
test/units/testsuite-47.service
test/units/testsuite-47.sh
test/units/testsuite-48.service
test/units/testsuite-48.sh
test/units/testsuite-49-namespaced.service
test/units/testsuite-49-non-namespaced.service
test/units/testsuite-49.service
test/units/testsuite-49.sh
test/units/testsuite-50.service
test/units/testsuite-50.sh
test/units/testsuite-51-repro-1.service
test/units/testsuite-51-repro-2.service
test/units/testsuite-51.service
test/units/testsuite-51.sh
test/units/testsuite-52.service
test/units/testsuite-52.sh
test/units/testsuite-53.service
test/units/testsuite-53.sh
test/units/testsuite-54.service
test/units/testsuite-54.sh
test/units/testsuite-55-slowgrowth.sh
test/units/testsuite-55-testbloat.service
test/units/testsuite-55-testchill.service
test/units/testsuite-55-testmunch.service
test/units/testsuite-55-workload.slice
test/units/testsuite-55.service
test/units/testsuite-55.sh
test/units/testsuite-57-binds-to.service
test/units/testsuite-57-bound-by.service
test/units/testsuite-57-fail.service
test/units/testsuite-57-prop-stop-one.service
test/units/testsuite-57-prop-stop-two.service
test/units/testsuite-57-short-lived.service
test/units/testsuite-57-short-lived.sh
test/units/testsuite-57-success.service
test/units/testsuite-57-uphold.service
test/units/testsuite-57.service
test/units/testsuite-57.sh
test/units/testsuite-58.service
test/units/testsuite-58.sh
test/units/testsuite-59.service
test/units/testsuite-59.sh
test/units/testsuite-60.service
test/units/testsuite-60.sh
test/units/testsuite-61.service
test/units/testsuite-61.sh
test/units/testsuite-62-1.service
test/units/testsuite-62-2.service
test/units/testsuite-62-3.service
test/units/testsuite-62-4.service
test/units/testsuite-62-5.service
test/units/testsuite-62.service
test/units/testsuite-62.sh
test/units/testsuite-63.service
test/units/testsuite-64.service
test/units/testsuite-64.sh
test/units/testsuite-65.service
test/units/testsuite-65.sh
test/units/testsuite-66-deviceisolation.service [new file with mode: 0644]
test/units/testsuite-66.service [new file with mode: 0644]
test/units/testsuite-66.sh [new file with mode: 0755]
test/units/testsuite.target
test/units/unit-.service.d/10-override.conf
test/units/unit-with-.service.d/20-override.conf
test/units/unit-with-multiple-.service.d/20-override.conf
test/units/unit-with-multiple-.service.d/30-override.conf
test/units/unit-with-multiple-dashes.service
test/units/unit-with-multiple-dashes.service.d/10-override.conf
test/units/unstoppable.service
units/integritysetup-pre.target [new file with mode: 0644]
units/integritysetup.target [new file with mode: 0644]
units/meson.build
units/remote-veritysetup.target
units/systemd-networkd.service.in
units/veritysetup-pre.target
units/veritysetup.target

index f89d1fc6fe4c008d40e3c89a603d3857c20d6201..c5b9d859dcf586fc27a33c08345a6398c3d6c923 100644 (file)
@@ -1,2 +1,11 @@
 *.[ch] whitespace=tab-in-indent,trailing-space
-test/dmidecode-dumps/*.bin binary
+*.gpg  binary generated
+*.bmp  binary
+
+# Mark files as "generated", i.e. no license applies to them.
+# This includes output from programs, directive lists generated by grepping
+# for all possibilities, samples from fuzzers, files from /proc, packet samples,
+# and anything else where no copyright can be asserted.
+#
+# Use 'git check-attr generated -- <path>' to query the attribute.
+[attr]generated
index 89d2f85cfbc885e42309599bd834d798ee77ebc0..9f4ef79bbb8414afeba3a41d4a87918b578d31bc 100755 (executable)
@@ -72,11 +72,17 @@ if [[ "$COMPILER" == clang ]]; then
     CC="clang-$COMPILER_VERSION"
     CXX="clang++-$COMPILER_VERSION"
     AR="llvm-ar-$COMPILER_VERSION"
-    # Latest LLVM stack deb packages provided by https://apt.llvm.org/
-    # Following snippet was borrowed from https://apt.llvm.org/llvm.sh
-    wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | apt-key add -
-    add-apt-repository -y "deb http://apt.llvm.org/$RELEASE/   llvm-toolchain-$RELEASE-$COMPILER_VERSION  main"
-    PACKAGES+=("clang-$COMPILER_VERSION" "lldb-$COMPILER_VERSION" "lld-$COMPILER_VERSION" "clangd-$COMPILER_VERSION")
+
+    # ATTOW llvm-11 got into focal-updates, which conflicts with llvm-11
+    # provided by the apt.llvm.org repositories. Let's use the system
+    # llvm package if available in such cases to avoid that.
+    if ! apt show --quiet "llvm-$COMPILER_VERSION" &>/dev/null; then
+        # Latest LLVM stack deb packages provided by https://apt.llvm.org/
+        # Following snippet was borrowed from https://apt.llvm.org/llvm.sh
+        wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | apt-key add -
+        add-apt-repository -y "deb http://apt.llvm.org/$RELEASE/   llvm-toolchain-$RELEASE-$COMPILER_VERSION  main"
+        PACKAGES+=("clang-$COMPILER_VERSION" "lldb-$COMPILER_VERSION" "lld-$COMPILER_VERSION" "clangd-$COMPILER_VERSION")
+    fi
 elif [[ "$COMPILER" == gcc ]]; then
     CC="gcc-$COMPILER_VERSION"
     CXX="g++-$COMPILER_VERSION"
index cc7d3aa41edd634ff0cafb4506d1cd147d83699c..3e65a61ea35c1e10088694b0bf7ba52f00f8e3af 100644 (file)
@@ -37,5 +37,5 @@ __pycache__/
 /mkosi.output/
 /mkosi.default
 # Ignore any mkosi config files with "local" in the name
-/mkosi.default.d/*local*.conf
+/mkosi.default.d/**/*local*.conf
 /tags
diff --git a/LICENSES/OFL-1.1.txt b/LICENSES/OFL-1.1.txt
new file mode 100644 (file)
index 0000000..33f3666
--- /dev/null
@@ -0,0 +1,97 @@
+Copyright (c) <dates>, <Copyright Holder> (<URL|email>),
+with Reserved Font Name <Reserved Font Name>.
+Copyright (c) <dates>, <additional Copyright Holder> (<URL|email>),
+with Reserved Font Name <additional Reserved Font Name>.
+Copyright (c) <dates>, <additional Copyright Holder> (<URL|email>).
+
+This Font Software is licensed under the SIL Open Font License, Version 1.1.
+This license is copied below, and is also available with a FAQ at:
+http://scripts.sil.org/OFL
+
+
+-----------------------------------------------------------
+SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
+-----------------------------------------------------------
+
+PREAMBLE
+The goals of the Open Font License (OFL) are to stimulate worldwide
+development of collaborative font projects, to support the font creation
+efforts of academic and linguistic communities, and to provide a free and
+open framework in which fonts may be shared and improved in partnership
+with others.
+
+The OFL allows the licensed fonts to be used, studied, modified and
+redistributed freely as long as they are not sold by themselves. The
+fonts, including any derivative works, can be bundled, embedded,
+redistributed and/or sold with any software provided that any reserved
+names are not used by derivative works. The fonts and derivatives,
+however, cannot be released under any other type of license. The
+requirement for fonts to remain under this license does not apply
+to any document created using the fonts or their derivatives.
+
+DEFINITIONS
+"Font Software" refers to the set of files released by the Copyright
+Holder(s) under this license and clearly marked as such. This may
+include source files, build scripts and documentation.
+
+"Reserved Font Name" refers to any names specified as such after the
+copyright statement(s).
+
+"Original Version" refers to the collection of Font Software components as
+distributed by the Copyright Holder(s).
+
+"Modified Version" refers to any derivative made by adding to, deleting,
+or substituting -- in part or in whole -- any of the components of the
+Original Version, by changing formats or by porting the Font Software to a
+new environment.
+
+"Author" refers to any designer, engineer, programmer, technical
+writer or other person who contributed to the Font Software.
+
+PERMISSION & CONDITIONS
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of the Font Software, to use, study, copy, merge, embed, modify,
+redistribute, and sell modified and unmodified copies of the Font
+Software, subject to the following conditions:
+
+1) Neither the Font Software nor any of its individual components,
+in Original or Modified Versions, may be sold by itself.
+
+2) Original or Modified Versions of the Font Software may be bundled,
+redistributed and/or sold with any software, provided that each copy
+contains the above copyright notice and this license. These can be
+included either as stand-alone text files, human-readable headers or
+in the appropriate machine-readable metadata fields within text or
+binary files as long as those fields can be easily viewed by the user.
+
+3) No Modified Version of the Font Software may use the Reserved Font
+Name(s) unless explicit written permission is granted by the corresponding
+Copyright Holder. This restriction only applies to the primary font name as
+presented to the users.
+
+4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
+Software shall not be used to promote, endorse or advertise any
+Modified Version, except to acknowledge the contribution(s) of the
+Copyright Holder(s) and the Author(s) or with their explicit written
+permission.
+
+5) The Font Software, modified or unmodified, in part or in whole,
+must be distributed entirely under this license, and must not be
+distributed under any other license. The requirement for fonts to
+remain under this license does not apply to any document created
+using the Font Software.
+
+TERMINATION
+This license becomes null and void if any of the above conditions are
+not met.
+
+DISCLAIMER
+THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
+OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
+COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
+DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
+OTHER DEALINGS IN THE FONT SOFTWARE.
index 3c28de51b1805845b51668a23e47572a98caa881..2f825c44bec2fbff9bbe9c63aec1f799ead63dd2 100644 (file)
@@ -2,7 +2,7 @@
 
 ## Main License
 
-The systemd project uses single-line references to Unique Licese Identifiers as
+The systemd project uses single-line references to Unique License Identifiers as
 defined by the Linux Foundation's SPDX project (https://spdx.org/). The line in
 each individual source file identifies the license applicable to that file.
 
@@ -47,7 +47,7 @@ The following exceptions apply:
    - src/basic/siphash24.h
    - src/systemctl/systemd-sysv-install.SKELETON
    - tools/check-includes.pl
-   - all examples, code and scripts, under man/ except where otherwise noted
+   - all examples under man/
  * the following sources are under **Public Domain** (LicenseRef-murmurhash2-public-domain):
    - src/basic/MurmurHash2.c
    - src/basic/MurmurHash2.h
@@ -56,6 +56,7 @@ The following exceptions apply:
    - src/libsystemd/sd-journal/lookup3.h
  * the tools/chromiumos/gen_autosuspend_rules.py script is licensed under the
    **BSD-3-Clause** license.
+ * Heebo fonts under docs/fonts/ are licensed under the **SIL Open Font License 1.1**,
  * any files under test/ without an explicit license we assume non-copyrightable
    (eg: computer-generated fuzzer data)
 
diff --git a/TODO b/TODO
index f670370a8e1a4d5e96b815fd24d13eeac5905ba0..efef0a5a373a36a95ada0035b069cddc9a062dd1 100644 (file)
--- a/TODO
+++ b/TODO
@@ -1248,10 +1248,6 @@ Features:
     fallback logic to get a regular user created on uninitialized systems.
   - store PKCS#11 + FIDO2 token info in LUKS2 header, compatible with
     systemd-cryptsetup, so that it can unlock homed volumes
-  - try to unmount in regular intervals when home dir was busy when we
-    tried because idle.
-  - keep an fd to the homedir open at all times, to keep the fs pinned
-    (autofs and such) while user is logged in.
 
 * add a new switch --auto-definitions=yes/no or so to systemd-repart. If
   specified, synthesize a definition automatically if we can: enlarge last
diff --git a/coccinelle/strdupa.cocci b/coccinelle/strdupa.cocci
new file mode 100644 (file)
index 0000000..665736e
--- /dev/null
@@ -0,0 +1,11 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+@@
+expression x;
+@@
+- strdupa(x)
++ strdupa_safe(x)
+@@
+expression x, n;
+@@
+- strndupa(x, n)
++ strndupa_safe(x, n)
diff --git a/docs/.gitattributes b/docs/.gitattributes
new file mode 100644 (file)
index 0000000..dbe845e
--- /dev/null
@@ -0,0 +1,2 @@
+*.png    binary generated
+*.woff   binary
index b3c197250a1ce034a9bd213b5f98ee1f017575b1..f2c877ccebf8d2df47d0548b8aeffeaf19e6b9db 100644 (file)
@@ -365,10 +365,11 @@ SPDX-License-Identifier: LGPL-2.1-or-later
 
 - Avoid fixed-size string buffers, unless you really know the maximum size and
   that maximum size is small. It is often nicer to use dynamic memory,
-  `alloca()` or VLAs. If you do allocate fixed-size strings on the stack, then
-  it is probably only OK if you either use a maximum size such as `LINE_MAX`,
-  or count in detail the maximum size a string can have. (`DECIMAL_STR_MAX` and
-  `DECIMAL_STR_WIDTH` macros are your friends for this!)
+  `alloca_safe()` or VLAs. If you do allocate fixed-size strings on the stack,
+  then it is probably only OK if you either use a maximum size such as
+  `LINE_MAX`, or count in detail the maximum size a string can
+  have. (`DECIMAL_STR_MAX` and `DECIMAL_STR_WIDTH` macros are your friends for
+  this!)
 
   Or in other words, if you use `char buf[256]` then you are likely doing
   something wrong!
@@ -376,13 +377,20 @@ SPDX-License-Identifier: LGPL-2.1-or-later
 - Make use of `_cleanup_free_` and friends. It makes your code much nicer to
   read (and shorter)!
 
-- Use `alloca()`, but never forget that it is not OK to invoke `alloca()`
-  within a loop or within function call parameters. `alloca()` memory is
-  released at the end of a function, and not at the end of a `{}` block. Thus,
-  if you invoke it in a loop, you keep increasing the stack pointer without
-  ever releasing memory again. (VLAs have better behavior in this case, so
-  consider using them as an alternative.)  Regarding not using `alloca()`
-  within function parameters, see the BUGS section of the `alloca(3)` man page.
+- Do not use `alloca()`, `strdupa()` or `strndupa()` directly. Use
+  `alloca_safe()`, `strdupa_safe()` or `strndupa_safe()` instead. (The
+  difference is that the latter include an assertion that the specified size is
+  below a safety threshold, so that the program rather aborts than runs into
+  possible stack overruns.)
+
+- Use `alloca_safe()`, but never forget that it is not OK to invoke
+  `alloca_safe()` within a loop or within function call
+  parameters. `alloca_safe()` memory is released at the end of a function, and
+  not at the end of a `{}` block. Thus, if you invoke it in a loop, you keep
+  increasing the stack pointer without ever releasing memory again. (VLAs have
+  better behavior in this case, so consider using them as an alternative.)
+  Regarding not using `alloca_safe()` within function parameters, see the BUGS
+  section of the `alloca(3)` man page.
 
 - If you want to concatenate two or more strings, consider using `strjoina()`
   or `strjoin()` rather than `asprintf()`, as the latter is a lot slower. This
index c4d3df85bead45768a2bdcd3cb3ba9c7a463cf8f..67ebcf3b96ace39c4352b731459194d52715ddc8 100644 (file)
@@ -44,3 +44,49 @@ See [reporting of security vulnerabilities](SECURITY.md).
 We'd like to apologize in advance if we are not able to process and reply to your issue or PR right-away. We have a lot of work to do, but we are trying our best!
 
 Thank you very much for your contributions!
+
+# Backward Compatibility And External Dependencies
+
+We strive to keep backward compatibility where possible and reasonable. The following are general guidelines, not hard
+rules, and case-by-case exceptions might be applied at the discretion of the maintainers. The current set of build time
+and runtime dependencies are documented in the [README](../README).
+
+## New features
+
+It is fine for new features/functionality/tools/daemons to require bleeding edge external dependencies, provided there
+are runtime and build time graceful fallbacks (e.g.: daemon will not be built, runtime functionality will be skipped with
+clear log message).
+In case a new feature is added to both `systemd` and one of its dependencies, we expect the corresponding feature code to
+be merged upstream in the dependency before accepting our side of the implementation.
+Making use of new kernel syscalls can be achieved through compat wrappers in our tree (see: `src/basic/missing_syscall_def.h`),
+and does not need to wait for glibc support.
+
+## External Build/Runtime Dependencies
+
+It is often tempting to bump external dependencies minimum versions to cut cruft, and in general it's an essential part
+of the maintenance process. But as a generic rule, existing dependencies should not be bumped without very strong
+reasons. When possible, we try to keep compatibility with the most recent LTS releases of each mainstream distribution
+for optional components, and with all currently maintained (i.e.: not EOL) LTS releases for core components. When in
+doubt, ask before committing time to work on contributions if it's not clear that cutting support would be obviously
+acceptable.
+
+## Kernel Requirements
+
+Same principles as with other dependencies should be applied. It is fine to require newer kernel versions for additional
+functionality or optional features, but very strong reasons should be required for breaking compatibility for existing
+functionality, especially for core components. It is not uncommon, for example, for embedded systems to be stuck on older
+kernel versions due to hardware requirements, so do not assume everybody is running with latest and greatest at all times.
+In general, [currently maintained LTS branches](https://www.kernel.org/category/releases.html) should keep being supported
+for existing functionality, especially for core components.
+
+## `libsystemd.so`
+
+`libsystemd.so` is a shared public library, so breaking ABI/API compatibility creates a lot of work for its users, and should
+always be avoided apart from the most extreme circumstances. For example, always add a new interface instead of modifying
+the signature of an existing function. It is fine to mark an interface as deprecated to gently nudge users toward a newer one,
+but in general support for the old one should be maintained whenever possible.
+Symbol versioning and the compiler's deprecated attribute should be used when managing the lifetime of a public interface.
+
+## `libudev.so`
+
+`libudev.so` is a shared public library, and is still maintained, but should not gain new symbols at this point.
index 5b7c01d149043ed6fbe4a17fdb15713a9cabed31..aba9ede259e95736ad0c2ae615a8e7eb1cd7d894 100644 (file)
@@ -50,6 +50,10 @@ All tools:
   useful for debugging. Currently only supported by
   `systemd-cryptsetup-generator`.
 
+* `$SYSTEMD_INTEGRITYTAB` â€” if set, use this path instead of
+  `/etc/integritytab`. Only useful for debugging. Currently only supported by
+  `systemd-integritysetup-generator`.
+
 * `$SYSTEMD_VERITYTAB` â€” if set, use this path instead of
   `/etc/veritytab`. Only useful for debugging. Currently only supported by
   `systemd-veritysetup-generator`.
@@ -364,3 +368,10 @@ disk images with `--image=` or similar:
   against any of the certificates in `/etc/verity.d/*.crt` (and similar
   directores in `/usr/lib/`, `/run`, â€¦) or passed to the kernel for validation
   against its built-in certificates.
+
+`systemd-cryptsetup`:
+
+* `$SYSTEMD_CRYPTSETUP_USE_TOKEN_MODULE` â€“ takes a boolean, which controls
+  whether to use the libcryptsetup "token" plugin module logic even when
+  activating via FIDO2, PKCS#11, TPM2, i.e. mechanisms natively supported by
+  `systemd-cryptsetup`. Defaults to enabled.
index 7ca30486a6b651277bb9e976ecef932615426a6a..1d84efc8ae41880a4673603e6fb42e8f54677e67 100644 (file)
@@ -286,7 +286,7 @@ following contents:
         {
             "type": "cppdbg",
             "program": "/usr/lib/systemd/systemd",
-            "processId": "${command:pickProcess}",
+            "processId": "${command:pickRemoteProcess}",
             "request": "attach",
             "name": "systemd",
             "pipeTransport": {
index 925b4adb14307b3875fabf634a56dec222efeae6..d543031261687d57af4bda4862c3ee318633b808 100644 (file)
@@ -1,4 +1,5 @@
 # Site settings
+# SPDX-License-Identifier: LGPL-2.1-or-later
 title: systemd
 baseurl: "" # the subpath of your site, e.g. /blog/
 url: "http://systemd.io" # the base hostname & protocol for your site
index e103a278c4032e0861770aa269e045c36a4df6f8..ebde9dc7b0b45f9115f6cda160a88e34937cb431 100644 (file)
@@ -1,3 +1,5 @@
+<!-- SPDX-License-Identifier: LGPL-2.1-or-later -->
+
 <footer class="site-footer">
   <p>&copy; systemd, 2021</p>
 
index 3ff4bbe0b8e916c6d72db33cf4ef08329c1e8ced..cccc8855181f23a5c519f92b960a841199d01626 100644 (file)
@@ -1,3 +1,5 @@
+<!-- SPDX-License-Identifier: LGPL-2.1-or-later -->
+
 <head>
   <meta charset="utf-8">
   <meta http-equiv="X-UA-Compatible" content="IE=edge">
index 4e885fbe7156626341e23ee6be6032facca41f0c..341971df703f1d4641791b334462bc1127cc702a 100644 (file)
@@ -1,3 +1,5 @@
+<!-- SPDX-License-Identifier: LGPL-2.1-or-later -->
+
 <header class="site-header">
 
   <div class="wrapper">
index 672aa0cd589cbb0fde6269afce15ddcd60d524a0..4649fda737eb9e7ed18c6077d35759ed7cede48b 100644 (file)
@@ -1,4 +1,6 @@
 <!DOCTYPE html>
+<!-- SPDX-License-Identifier: LGPL-2.1-or-later -->
+
 <html>
 
   {% include head.html %}
index e59c88af38833cedcd327f90d31f04aebb79430a..72fc5a46cf54b229ed626d5f3163bd786ac90ba4 100644 (file)
@@ -1,4 +1,5 @@
 <svg xmlns="http://www.w3.org/2000/svg" width="202" height="26">
+    <!-- SPDX-License-Identifier: LGPL-2.1-or-later -->
     <path overflow="visible" font-weight="400" d="M0 0v26h10v-4H4V4h6V0zm76 0v4h6v18h-6v4h10V0z" style="line-height:normal;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000;text-transform:none;text-orientation:mixed;white-space:normal;shape-padding:0;isolation:auto;mix-blend-mode:normal;solid-color:#000;solid-opacity:1" color="#000" font-family="sans-serif" fill="#201a26"/>
     <path word-spacing="0" letter-spacing=".2" font-size="12" font-weight="700" style="line-height:1.25;-inkscape-font-specification:'Heebo Bold';text-align:start" d="M113.498 14.926q-4.5-.96-4.5-3.878 0-1.079.609-1.981.621-.902 1.781-1.441 1.16-.54 2.707-.54 1.63 0 2.848.528 1.219.516 1.875 1.453.656.926.656 2.121h-3.539q0-.762-.457-1.183-.457-.434-1.394-.434-.774 0-1.243.363-.457.364-.457.938 0 .55.516.89.527.34 1.781.575 1.5.28 2.543.738 1.043.445 1.653 1.242.62.797.62 2.027 0 1.114-.667 2.004-.657.88-1.887 1.383-1.219.504-2.836.504-1.711 0-2.965-.621-1.242-.633-1.898-1.617-.645-.985-.645-2.051h3.34q.036.914.656 1.36.621.433 1.594.433.902 0 1.383-.34.492-.351.492-.937 0-.364-.223-.61-.21-.258-.773-.48-.55-.223-1.57-.446zm19.384-7.606l-5.086 14.58q-.293.831-.726 1.523-.434.703-1.266 1.195-.832.504-2.098.504-.457 0-.75-.048-.281-.046-.785-.176v-2.672q.176.02.527.02.95 0 1.418-.293.47-.293.715-.961l.352-.926-4.43-12.738h3.797l2.262 7.687 2.285-7.687zm5.884 7.606q-4.5-.96-4.5-3.878 0-1.079.61-1.981.62-.902 1.781-1.441 1.16-.54 2.707-.54 1.629 0 2.848.528 1.218.516 1.875 1.453.656.926.656 2.121h-3.539q0-.762-.457-1.183-.457-.434-1.395-.434-.773 0-1.242.363-.457.364-.457.938 0 .55.516.89.527.34 1.781.575 1.5.28 2.543.738 1.043.445 1.652 1.242.621.797.621 2.027 0 1.114-.668 2.004-.656.88-1.886 1.383-1.219.504-2.836.504-1.711 0-2.965-.621-1.242-.633-1.899-1.617-.644-.985-.644-2.051h3.34q.036.914.656 1.36.621.433 1.594.433.902 0 1.383-.34.492-.351.492-.937 0-.364-.223-.61-.21-.258-.773-.48-.551-.223-1.57-.446zm13.983 2.403q.574 0 .984-.082v2.66q-.914.328-2.086.328-3.727 0-3.727-3.797V9.899h-1.793V7.321h1.793v-3.14h3.54v3.14h2.132v2.578h-2.133v6.129q0 .75.293 1.031.293.27.997.27zm14.228-2.519h-8.016q.2 1.183.985 1.886.785.691 2.015.691.914 0 1.688-.34.785-.351 1.336-1.042l1.699 1.957q-.668.96-1.957 1.617-1.278.656-3 .656-1.946 0-3.387-.82-1.43-.82-2.203-2.227-.762-1.406-.762-3.105v-.446q0-1.898.715-3.386.715-1.489 2.063-2.32 1.347-.844 3.187-.844 1.793 0 3.059.761 1.265.762 1.922 2.168.656 1.395.656 3.293zm-3.469-2.65q-.024-1.03-.574-1.628-.54-.598-1.617-.598-1.008 0-1.582.668-.563.668-.739 1.84h4.512zm19.923-5.073q1.934 0 2.989 1.148 1.054 1.148 1.054 3.727v8.039h-3.539V11.95q0-.797-.21-1.23-.212-.446-.61-.61-.387-.164-.984-.164-.715 0-1.219.352-.504.34-.797.972.02.082.02.27V20h-3.54v-8.015q0-.797-.21-1.242-.211-.445-.61-.621-.386-.176-.996-.176-.68 0-1.183.304-.492.293-.797.844V20h-3.539V7.32h3.316l.118 1.419q.633-.797 1.547-1.22.926-.433 2.086-.433 1.172 0 2.016.48.855.47 1.312 1.442.633-.926 1.582-1.418.961-.504 2.203-.504zM201.398 2v18h-3.187l-.176-1.359q-1.243 1.594-3.212 1.594-1.535 0-2.66-.82-1.113-.832-1.699-2.285-.574-1.454-.574-3.317v-.246q0-1.934.574-3.398.586-1.465 1.7-2.274 1.124-.808 2.683-.808 1.805 0 3.012 1.37V2.001zm-5.672 15.376q1.488 0 2.133-1.266v-4.898q-.61-1.266-2.11-1.266-1.207 0-1.77.984-.55.985-.55 2.637v.246q0 1.629.54 2.602.55.96 1.757.96z" font-family="Heebo" fill="#201a26"/>
     <path d="M45 13L63 3v20z" fill="#30d475"/>
index 9ffaf5933c59b9dea76de2452863f496428898e3..37985c36a645dedb1f3ab4031dd020186a844796 100644 (file)
@@ -1,4 +1,5 @@
 <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16">
+    <!-- SPDX-License-Identifier: LGPL-2.1-or-later -->
     <g transform="translate(380 -506.52)">
         <rect ry="16.875" rx="16.875" y="2409.281" x="4128.568" height="90" width="90" fill="#201a26" transform="matrix(.17778 0 0 .17778 -1113.968 78.203)" stroke-width="5.625"/>
         <g fill="none" stroke="#fff" stroke-width="2">
index 951e3f5a48bed96b989cfd725d50693703ff1bc8..6f81452b65c3266c964b90d5db59d8b83940f5ab 100644 (file)
@@ -1,3 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+
 @font-face {
     font-family: 'Heebo';
     src: url('fonts/heebo-regular.woff');
index 7bdd3f93d8724ca687f72a9fbe8240fab79e201f..e669d0d21f1be0319dbd9006f6bf2e91b75d2750 100755 (executable)
@@ -1,4 +1,5 @@
 #!/usr/bin/env python3
+# SPDX-License-Identifier: LGPL-2.1-or-later
 
 from html.parser import HTMLParser
 from enum import Enum
index 6f3a88f840ab1e0d7f0d96eee7dcdb208c4ca5d9..0ce79cd97e998db7b29a8ae1847b79caae4e3f77 100755 (executable)
@@ -1,4 +1,5 @@
 #!/usr/bin/env python3
+# SPDX-License-Identifier: LGPL-2.1-or-later
 
 import re
 import sys
index a958cde7df84d0d8f1285ced7e87fed182bb661d..73cacc6107a6dad5c49ff6d28dce64d552c30b4f 100644 (file)
         </para></listitem>
       </varlistentry>
 
+      <varlistentry>
+        <term><option>set-timeout</option> <replaceable>TIMEOUT</replaceable></term>
+        <term><option>set-timeout-oneshot</option> <replaceable>TIMEOUT</replaceable></term>
+
+        <listitem><para>Sets the boot loader menu timeout in seconds. The <option>set-timeout-oneshot</option>
+        command will set the timeout only for the next boot. See
+        <citerefentry><refentrytitle>systemd.time</refentrytitle><manvolnum>7</manvolnum></citerefentry>
+        for details about the syntax of time spans.</para>
+
+        <para>If this is set to <option>menu-hidden</option> or <option>0</option> no menu is shown and
+        the default entry will be booted immediately, while setting this to <option>menu-force</option>
+        disables the timeout while always showing the menu. When an empty string ("") is specified the
+        bootloader will revert to its default menu timeout.</para></listitem>
+      </varlistentry>
+
     </variablelist>
   </refsect1>
 
index e8c538cc85c43c115f612aa8bebd9714330782ad..ac5c6ef6664b82139bf1d7ee0a02b5f9ba919d5a 100644 (file)
         of the current PCR state.</para></listitem>
       </varlistentry>
 
+      <varlistentry>
+        <term><option>token-timeout=</option></term>
+
+        <listitem><para>Specifies how long to wait at most for configured security devices (i.e. FIDO2,
+        PKCS#11, TPM2) to show up. Takes a time value in seconds (but other time units may be specified too,
+        see <citerefentry><refentrytitle>systemd.time</refentrytitle><manvolnum>7</manvolnum></citerefentry>
+        for supported formats). Defaults to 30s. Once the specified timeout elapsed authentication via
+        password is attempted. Note that this timeout applies to waiting for the security device to show up â€”
+        it does not apply to the PIN prompt for the device (should one be needed) or similar. Pass 0 to turn
+        off the time-out and wait forever.</para></listitem>
+      </varlistentry>
+
       <varlistentry>
         <term><option>try-empty-password=</option></term>
 
       <varlistentry>
         <term><option>x-systemd.device-timeout=</option></term>
 
-        <listitem><para>Specifies how long systemd should wait for a device to show up
-        before giving up on the entry. The argument is a time in seconds or explicitly
-        specified units of
-        <literal>s</literal>,
-        <literal>min</literal>,
-        <literal>h</literal>,
-        <literal>ms</literal>.
+        <listitem><para>Specifies how long systemd should wait for a block device to show up before
+        giving up on the entry. The argument is a time in seconds or explicitly specified units of
+        <literal>s</literal>, <literal>min</literal>, <literal>h</literal>, <literal>ms</literal>.
         </para></listitem>
       </varlistentry>
 
index 245ebcee003f5af76db050e2b58d6ec6911402a9..c2b1ec6c9b2855e6cfd3734c80ee7205b7d08daf 100644 (file)
         node is not allowed if any of the other storage backends are used.</para></listitem>
       </varlistentry>
 
+      <varlistentry>
+        <term><option>--drop-caches=</option><replaceable>BOOL</replaceable></term>
+
+        <listitem><para>Automatically flush OS file system caches on logout. This is useful in combination
+        with the fscrypt storage backend to ensure the OS does not keep decrypted versions of the files and
+        directories in memory (and accessible) after logout. This option is also supported on other backends,
+        but should not bring any benefit there. Defaults to off, except if the selected storage backend is
+        fscrypt, where it defaults to on. Note that flushing OS caches will negatively influence performance
+        of the OS shortly after logout.</para></listitem>
+      </varlistentry>
+
       <varlistentry>
         <term><option>--fs-type=</option><replaceable>TYPE</replaceable></term>
 
diff --git a/man/integritytab.xml b/man/integritytab.xml
new file mode 100644 (file)
index 0000000..c2ad257
--- /dev/null
@@ -0,0 +1,161 @@
+<?xml version="1.0"?>
+<!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
+  "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+<!--
+  SPDX-License-Identifier: LGPL-2.1-or-later
+
+-->
+<refentry id="integritytab" conditional='HAVE_LIBCRYPTSETUP' xmlns:xi="http://www.w3.org/2001/XInclude">
+
+  <refentryinfo>
+    <title>integritytab</title>
+    <productname>systemd</productname>
+  </refentryinfo>
+
+  <refmeta>
+    <refentrytitle>integritytab</refentrytitle>
+    <manvolnum>5</manvolnum>
+  </refmeta>
+
+  <refnamediv>
+    <refname>integritytab</refname>
+    <refpurpose>Configuration for integrity block devices</refpurpose>
+  </refnamediv>
+
+  <refsynopsisdiv>
+    <para><filename>/etc/integritytab</filename></para>
+  </refsynopsisdiv>
+
+  <refsect1>
+    <title>Description</title>
+
+    <para>The <filename>/etc/integritytab</filename> file describes
+    integrity protected block devices that are set up during
+    system boot.</para>
+
+    <para>Empty lines and lines starting with the <literal>#</literal>
+    character are ignored. Each of the remaining lines describes one
+    verity integrity protected block device. Fields are delimited by
+    white space.</para>
+
+    <para>Each line is in the form<programlisting><replaceable>volume-name</replaceable> <replaceable>block-device</replaceable>
+    <replaceable>[keyfile|-]</replaceable> <replaceable>[options|-]</replaceable></programlisting>
+    The first two fields are mandatory, the remaining two are optional and only required if user specified non-default options during integrity format.</para>
+
+    <para>The first field contains the name of the resulting integrity volume; its block device is set up
+    below <filename>/dev/mapper/</filename>.</para>
+
+    <para>The second field contains a path to the underlying block device, or a specification of a block device via
+    <literal>UUID=</literal> followed by the UUID,
+    <literal>PARTUUID=</literal> followed by the partition UUID,
+    <literal>LABEL=</literal> followed by the label,
+    <literal>PARTLABEL=</literal> followed by the partition label,
+    </para>
+
+    <para>The third field if present contains an absolute filename path to a key file or a <literal>-</literal>
+    to specify none.  When the filename is present, the "integrity-algorithm" defaults to <literal>hmac-sha256</literal>
+    with the key length derived from the number of bytes in the key file.  At this time the only supported integrity algorithm
+    when using key file is hmac-sha256.  The maximum size of the key file is 4096 bytes.
+    </para>
+
+     <para>The fourth field, if present, is a comma-delimited list of options or a <literal>-</literal> to specify none. The following options are
+    recognized:</para>
+      <variablelist>
+
+      <varlistentry>
+        <term><option>allow-discards</option></term>
+
+        <listitem><para>
+        Allow the use of discard (TRIM) requests for the device.
+        This option is available since the Linux kernel version 5.7.
+        </para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><option>journal-watermark=[0..100]%</option></term>
+
+        <listitem><para>
+        Journal watermark in percent. When the journal percentage exceeds this watermark, the journal flush will be started.  Setting a value of
+        "0%" uses default value.
+        </para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><option>journal-commit-time=[0..N]</option></term>
+
+        <listitem><para>
+        Commit time in milliseconds. When this time passes (and no explicit flush operation was issued), the journal is written.  Setting a value of
+        zero uses default value.
+        </para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><option>data-device=/dev/disk/by-...</option></term>
+
+        <listitem><para>
+        Specify a separate block device that contains existing data. The second field specified in the
+        integritytab for block device then will contain calculated integrity tags and journal for data-device,
+        but not the end user data.
+        </para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><option>integrity-algorithm=[crc32c|crc32|sha1|sha256|hmac-sha256]</option></term>
+
+        <listitem><para>
+        The algorithm used for integrity checking.  The default is crc32c. Must match option used during format.
+        </para></listitem>
+      </varlistentry>
+    </variablelist>
+
+    <para>At early boot and when the system manager configuration is
+    reloaded, this file is translated into native systemd units by
+    <citerefentry><refentrytitle>systemd-integritysetup-generator</refentrytitle><manvolnum>8</manvolnum></citerefentry>.</para>
+  </refsect1>
+
+  <refsect1>
+    <title>Examples</title>
+    <example>
+      <title>/etc/integritytab</title>
+      <para>Set up two integrity protected block devices. </para>
+
+      <programlisting>home PARTUUID=4973d0b8-1b15-c449-96ec-94bab7f6a7b8 - journal-commit-time=10,allow-discards,journal-watermark=55%
+data PARTUUID=5d4b1808-be76-774d-88af-03c4c3a41761 - allow-discards
+</programlisting>
+    </example>
+
+    <example>
+      <title>/etc/integritytab</title>
+      <para>Set up 1 integrity protected block device using defaults </para>
+
+      <programlisting>home PARTUUID=4973d0b8-1b15-c449-96ec-94bab7f6a7b8</programlisting>
+    </example>
+
+    <example>
+      <title>/etc/integritytab</title>
+      <para>Set up 1 integrity device using existing data block device which contains user data </para>
+
+      <programlisting>home PARTUUID=4973d0b8-1b15-c449-96ec-94bab7f6a7b8 - data-device=/dev/disk/by-uuid/9276d9c0-d4e3-4297-b4ff-3307cd0d092f</programlisting>
+    </example>
+
+    <example>
+      <title>/etc/integritytab</title>
+      <para>Set up 1 integrity device using a HMAC key file using defaults </para>
+
+      <programlisting>home PARTUUID=4973d0b8-1b15-c449-96ec-94bab7f6a7b8 /etc/hmac.key</programlisting>
+    </example>
+
+  </refsect1>
+
+  <refsect1>
+    <title>See Also</title>
+    <para>
+      <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+      <citerefentry><refentrytitle>systemd-integritysetup@.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+      <citerefentry><refentrytitle>systemd-integritysetup-generator</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+      <citerefentry project='die-net'><refentrytitle>integritysetup</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+    </para>
+  </refsect1>
+
+</refentry>
index f546a1161a5fa66497fb0e23c57f7b00371bde14..2093edd05c74beec862f47cde9b6a693ba6726b3 100644 (file)
         <term><varname>systemd.default_timeout_start_sec=</varname></term>
 
         <listitem>
-          <para>Overwrites the default start job timeout <varname>DefaultTimeoutStartSec=</varname> at boot. For details,
-          see <citerefentry><refentrytitle>systemd-system.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>.</para>
+          <para>Overrrides the default start job timeout <varname>DefaultTimeoutStartSec=</varname> at
+          boot. For details, see
+          <citerefentry><refentrytitle>systemd-system.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>.</para>
         </listitem>
       </varlistentry>
 
         <term><varname>systemd.watchdog_device=</varname></term>
 
         <listitem>
-          <para>Overwrites the watchdog device path <varname>WatchdogDevice=</varname>. For details, see
+          <para>Overrrides the watchdog device path <varname>WatchdogDevice=</varname>. For details, see
+          <citerefentry><refentrytitle>systemd-system.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>.</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><varname>systemd.watchdog_sec=</varname></term>
+
+        <listitem>
+          <para>Overrrides the watchdog timeout settings otherwise configured with
+          <varname>RuntimeWatchdog=</varname>, <varname>RebootWatchdog=</varname> and
+          <varname>KExecWatchdogSec=</varname>. Takes a time value (if no unit is specified, seconds is the
+          implicitly assumed time unit) or the special strings <literal>off</literal> or
+          <literal>default</literal>. For details, see
           <citerefentry><refentrytitle>systemd-system.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>.</para>
         </listitem>
       </varlistentry>
index ffbd897a1fdd467d59c594579222c6c3d0ecfa84..26e83dfcab8d5b8943e10145ed009b6416b2d932 100644 (file)
         will be stored as an EFI variable in that case, overriding this option.
         </para>
 
-        <para>If the timeout is disabled, the default entry will be booted
-        immediately. The menu can be shown by pressing and holding a key before
-        systemd-boot is launched.</para>
+        <para>If set to <literal>menu-hidden</literal> or <literal>0</literal> no menu
+        is shown and the default entry will be booted immediately. The menu can be shown
+        by pressing and holding a key before systemd-boot is launched. Setting this to
+        <literal>menu-force</literal> disables the timeout while always showing the menu.</para>
         </listitem>
       </varlistentry>
 
index f9c69f184625a6e9d6f9a97562ac9228d556ff81..ad7cc41c98347a62a2c55c3304b3485faa26ac60 100644 (file)
@@ -24,6 +24,7 @@ manpages = [
  ['hostname', '5', [], ''],
  ['hostnamectl', '1', [], 'ENABLE_HOSTNAMED'],
  ['hwdb', '7', [], 'ENABLE_HWDB'],
+ ['integritytab', '5', [], 'HAVE_LIBCRYPTSETUP'],
  ['journal-remote.conf', '5', ['journal-remote.conf.d'], 'HAVE_MICROHTTPD'],
  ['journal-upload.conf', '5', ['journal-upload.conf.d'], 'HAVE_MICROHTTPD'],
  ['journalctl', '1', [], ''],
@@ -882,6 +883,11 @@ manpages = [
   '8',
   ['systemd-initctl', 'systemd-initctl.socket'],
   'HAVE_SYSV_COMPAT'],
+ ['systemd-integritysetup-generator', '8', [], 'HAVE_LIBCRYPTSETUP'],
+ ['systemd-integritysetup@.service',
+  '8',
+  ['systemd-integritysetup'],
+  'HAVE_LIBCRYPTSETUP'],
  ['systemd-journal-gatewayd.service',
   '8',
   ['systemd-journal-gatewayd', 'systemd-journal-gatewayd.socket'],
diff --git a/man/systemd-integritysetup-generator.xml b/man/systemd-integritysetup-generator.xml
new file mode 100644 (file)
index 0000000..23eab01
--- /dev/null
@@ -0,0 +1,48 @@
+<?xml version="1.0"?>
+<!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
+  "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+<!-- SPDX-License-Identifier: LGPL-2.1-or-later -->
+<refentry id="systemd-integritysetup-generator" conditional='HAVE_LIBCRYPTSETUP'>
+
+  <refentryinfo>
+    <title>systemd-integritysetup-generator</title>
+    <productname>systemd</productname>
+  </refentryinfo>
+
+  <refmeta>
+    <refentrytitle>systemd-integritysetup-generator</refentrytitle>
+    <manvolnum>8</manvolnum>
+  </refmeta>
+
+  <refnamediv>
+    <refname>systemd-integritysetup-generator</refname>
+    <refpurpose>Unit generator for integrity protected block devices</refpurpose>
+  </refnamediv>
+
+  <refsynopsisdiv>
+    <para><filename>/usr/lib/systemd/system-generators/systemd-integritysetup-generator</filename></para>
+  </refsynopsisdiv>
+
+  <refsect1>
+    <title>Description</title>
+
+    <para><filename>systemd-integritysetup-generator</filename> is a generator that translates <filename>/etc/integritytab</filename> entries into
+    native systemd units early at boot. This will create
+    <citerefentry><refentrytitle>systemd-integritysetup@.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+    units as necessary.</para>
+
+    <para><command>systemd-integritysetup-generator</command> implements
+    <citerefentry><refentrytitle>systemd.generator</refentrytitle><manvolnum>7</manvolnum></citerefentry>.</para>
+  </refsect1>
+
+  <refsect1>
+    <title>See Also</title>
+    <para>
+      <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+      <citerefentry><refentrytitle>systemd-integritysetup@.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+      <citerefentry project='die-net'><refentrytitle>integritysetup</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+    </para>
+  </refsect1>
+
+</refentry>
diff --git a/man/systemd-integritysetup@.service.xml b/man/systemd-integritysetup@.service.xml
new file mode 100644 (file)
index 0000000..24336c2
--- /dev/null
@@ -0,0 +1,95 @@
+<?xml version="1.0"?>
+<!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
+  "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+<!-- SPDX-License-Identifier: LGPL-2.1-or-later -->
+<refentry id="systemd-integritysetup@.service" conditional='HAVE_LIBCRYPTSETUP'>
+
+  <refentryinfo>
+    <title>systemd-integritysetup@.service</title>
+    <productname>systemd</productname>
+  </refentryinfo>
+
+  <refmeta>
+    <refentrytitle>systemd-integritysetup@.service</refentrytitle>
+    <manvolnum>8</manvolnum>
+  </refmeta>
+
+  <refnamediv>
+    <refname>systemd-integritysetup@.service</refname>
+    <refname>systemd-integritysetup</refname>
+    <refpurpose>Disk integrity protection logic</refpurpose>
+  </refnamediv>
+
+  <refsynopsisdiv>
+    <para><filename>systemd-integritysetup@.service</filename></para>
+    <para><filename>/usr/lib/systemd/systemd-integritysetup</filename></para>
+  </refsynopsisdiv>
+
+  <refsect1>
+    <title>Description</title>
+
+    <para><filename>systemd-integritysetup@.service</filename> is a service responsible for setting up integrity
+    protected block devices. It should be instantiated for each device that requires integrity
+    protection.</para>
+
+    <para>At early boot and when the system manager configuration is reloaded, entries from /etc/integritytab are converted into
+    <filename>systemd-integritysetup@.service</filename> units by
+    <citerefentry><refentrytitle>systemd-integritysetup-generator</refentrytitle><manvolnum>8</manvolnum></citerefentry>.</para>
+
+    <para><filename>systemd-integritysetup@.service</filename> calls <command>systemd-integritysetup</command>.</para>
+  </refsect1>
+
+  <refsect1>
+    <title>Commands</title>
+
+    <para>The following commands are understood by <command>systemd-integritysetup</command>:</para>
+
+    <variablelist>
+      <varlistentry>
+        <term>
+          <option>attach</option>
+          <replaceable>volume</replaceable>
+          <replaceable>device</replaceable>
+          [<replaceable>key-file|-</replaceable>]
+          [<replaceable>option(s)|-</replaceable>]
+        </term>
+
+        <listitem><para>Create a block device <replaceable>volume</replaceable> using
+        <replaceable>device</replaceable>. See integritytab man page and
+        <ulink url="https://www.kernel.org/doc/html/latest/admin-guide/device-mapper/dm-integrity.html">
+          Kernel dm-integrity</ulink> documentation for details.
+        </para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term>
+          <option>detach</option>
+          <replaceable>volume</replaceable>
+        </term>
+
+        <listitem><para>Detach (destroy) the block device
+        <replaceable>volume</replaceable>.</para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term>
+          <option>help</option>
+        </term>
+
+        <listitem><para>Print short information about command syntax.</para></listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+
+  <refsect1>
+    <title>See Also</title>
+    <para>
+      <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+      <citerefentry><refentrytitle>integritytab</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+      <citerefentry><refentrytitle>systemd-integritysetup-generator</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+      <citerefentry project='die-net'><refentrytitle>integritysetup</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+     </para>
+  </refsect1>
+
+</refentry>
index 177fe892a650c89a239118393eb8cebedfd11a59..f1695b6ddb2e51059a4f03de0049afdf261d9d00 100644 (file)
@@ -39,7 +39,7 @@
 
     <para>If the tool is invoked without the <option>--commit</option>
     switch, <filename>/etc/machine-id</filename> is initialized with a
-    valid, new machined ID if it is missing or empty. The new machine
+    valid, new machine ID if it is missing or empty. The new machine
     ID will be acquired in the following fashion:</para>
 
     <orderedlist>
index 2edc64ce176f6853ebefd70694133ee65acfae99..2a32e05bcc36ab0f8014568e2ebdcbcf9c528e8e 100644 (file)
@@ -52,6 +52,9 @@
       <listitem><para>The initial RAM disk (initrd) will be looked for in the <literal>.initrd</literal> PE
       section.</para></listitem>
 
+      <listitem><para>A compiled binary DeviceTree will be looked for in the <literal>.dtb</literal> PE
+      section.</para></listitem>
+
       <listitem><para>The kernel command line to pass to the invoked kernel will be looked for in the
       <literal>.cmdline</literal> PE section.</para></listitem>
 
     SecureBoot, or don't include a kernel command line PE section in the kernel image file. If a command line
     is accepted via EFI invocation parameters to the EFI binary it is measured into TPM PCR 8 (if a TPM is
     present).</para>
+
+    <para>If a DeviceTree is embedded in the <literal>.dtb</literal> section, it replaces an existing
+    DeviceTree in the corresponding EFI configuration table. systemd-stub will ask the firmware via the
+    <literal>EFI_DT_FIXUP_PROTOCOL</literal> for hardware specific fixups to the DeviceTree.</para>
   </refsect1>
 
   <refsect1>
     <programlisting>objcopy \
     --add-section .osrel=os-release --change-section-vma .osrel=0x20000 \
     --add-section .cmdline=cmdline.txt --change-section-vma .cmdline=0x30000 \
-    --add-section .splash=splash.bmp --change-section-vma .splash=0x40000 \
+    --add-section .dtb=devicetree.dtb --change-section-vma .dtb=0x40000 \
+    --add-section .splash=splash.bmp --change-section-vma .splash=0x100000 \
     --add-section .linux=vmlinux --change-section-vma .linux=0x2000000 \
     --add-section .initrd=initrd.cpio --change-section-vma .initrd=0x3000000 \
     /usr/lib/systemd/boot/efi/linuxx64.efi.stub \
index ca36a64debd29c54c44d1674a09b2aa991d7fefd..3805a010e2e779a558fb47c1f93c54c0ef90e6d1 100644 (file)
         <term><varname>RebootWatchdogSec=</varname></term>
         <term><varname>KExecWatchdogSec=</varname></term>
 
-        <listitem><para>Configure the hardware watchdog at runtime and at reboot. Takes a timeout value in seconds (or
-        in other time units if suffixed with <literal>ms</literal>, <literal>min</literal>, <literal>h</literal>,
-        <literal>d</literal>, <literal>w</literal>). If <varname>RuntimeWatchdogSec=</varname> is set to a non-zero
-        value, the watchdog hardware (<filename>/dev/watchdog</filename> or the path specified with
-        <varname>WatchdogDevice=</varname> or the kernel option <varname>systemd.watchdog-device=</varname>) will be
-        programmed to automatically reboot the system if it is not contacted within the specified timeout interval. The
-        system manager will ensure to contact it at least once in half the specified timeout interval. This feature
-        requires a hardware watchdog device to be present, as it is commonly the case in embedded and server
-        systems. Not all hardware watchdogs allow configuration of all possible reboot timeout values, in which case
-        the closest available timeout is picked. <varname>RebootWatchdogSec=</varname> may be used to configure the
-        hardware watchdog when the system is asked to reboot. It works as a safety net to ensure that the reboot takes
-        place even if a clean reboot attempt times out. Note that the <varname>RebootWatchdogSec=</varname> timeout
-        applies only to the second phase of the reboot, i.e. after all regular services are already terminated, and
-        after the system and service manager process (PID 1) got replaced by the <filename>systemd-shutdown</filename>
-        binary, see system <citerefentry><refentrytitle>bootup</refentrytitle><manvolnum>7</manvolnum></citerefentry>
-        for details. During the first phase of the shutdown operation the system and service manager remains running
-        and hence <varname>RuntimeWatchdogSec=</varname> is still honoured. In order to define a timeout on this first
-        phase of system shutdown, configure <varname>JobTimeoutSec=</varname> and <varname>JobTimeoutAction=</varname>
-        in the [Unit] section of the <filename>shutdown.target</filename> unit. By default
-        <varname>RuntimeWatchdogSec=</varname> defaults to 0 (off), and <varname>RebootWatchdogSec=</varname> to
-        10min. <varname>KExecWatchdogSec=</varname> may be used to additionally enable the watchdog when kexec
-        is being executed rather than when rebooting. Note that if the kernel does not reset the watchdog on kexec (depending
-        on the specific hardware and/or driver), in this case the watchdog might not get disabled after kexec succeeds
-        and thus the system might get rebooted, unless <varname>RuntimeWatchdogSec=</varname> is also enabled at the same time.
-        For this reason it is recommended to enable <varname>KExecWatchdogSec=</varname> only if
-        <varname>RuntimeWatchdogSec=</varname> is also enabled.
-        These settings have no effect if a hardware watchdog is not available.</para></listitem>
+        <listitem><para>Configure the hardware watchdog at runtime and at reboot. Takes a timeout value in
+        seconds (or in other time units if suffixed with <literal>ms</literal>, <literal>min</literal>,
+        <literal>h</literal>, <literal>d</literal>, <literal>w</literal>), or the special strings
+        <literal>off</literal> or <literal>default</literal>. If set to <literal>off</literal>
+        (alternatively: <literal>0</literal>) the watchdog logic is disabled: no watchdog device is opened,
+        configured, or pinged. If set to the special string <literal>default</literal> the watchdog is opened
+        and pinged in regular intervals, but the timeout is not changed from the default. If set to any other
+        time value the watchdog timeout is configured to the specified value (or a value close to it,
+        depending on hardware capabilities).</para>
+
+        <para>If <varname>RuntimeWatchdogSec=</varname> is set to a non-zero value, the watchdog hardware
+        (<filename>/dev/watchdog0</filename> or the path specified with <varname>WatchdogDevice=</varname> or
+        the kernel option <varname>systemd.watchdog-device=</varname>) will be programmed to automatically
+        reboot the system if it is not contacted within the specified timeout interval. The system manager
+        will ensure to contact it at least once in half the specified timeout interval. This feature requires
+        a hardware watchdog device to be present, as it is commonly the case in embedded and server
+        systems. Not all hardware watchdogs allow configuration of all possible reboot timeout values, in
+        which case the closest available timeout is picked.</para>
+
+        <para><varname>RebootWatchdogSec=</varname> may be used to configure the hardware watchdog when the
+        system is asked to reboot. It works as a safety net to ensure that the reboot takes place even if a
+        clean reboot attempt times out. Note that the <varname>RebootWatchdogSec=</varname> timeout applies
+        only to the second phase of the reboot, i.e. after all regular services are already terminated, and
+        after the system and service manager process (PID 1) got replaced by the
+        <filename>systemd-shutdown</filename> binary, see system
+        <citerefentry><refentrytitle>bootup</refentrytitle><manvolnum>7</manvolnum></citerefentry> for
+        details. During the first phase of the shutdown operation the system and service manager remains
+        running and hence <varname>RuntimeWatchdogSec=</varname> is still honoured. In order to define a
+        timeout on this first phase of system shutdown, configure <varname>JobTimeoutSec=</varname> and
+        <varname>JobTimeoutAction=</varname> in the [Unit] section of the
+        <filename>shutdown.target</filename> unit. By default <varname>RuntimeWatchdogSec=</varname> defaults
+        to 0 (off), and <varname>RebootWatchdogSec=</varname> to 10min.</para>
+
+        <para><varname>KExecWatchdogSec=</varname> may be used to additionally enable the watchdog when kexec
+        is being executed rather than when rebooting. Note that if the kernel does not reset the watchdog on
+        kexec (depending on the specific hardware and/or driver), in this case the watchdog might not get
+        disabled after kexec succeeds and thus the system might get rebooted, unless
+        <varname>RuntimeWatchdogSec=</varname> is also enabled at the same time.  For this reason it is
+        recommended to enable <varname>KExecWatchdogSec=</varname> only if
+        <varname>RuntimeWatchdogSec=</varname> is also enabled.</para>
+
+        <para>These settings have no effect if a hardware watchdog is not available.</para></listitem>
       </varlistentry>
 
       <varlistentry>
 
         <listitem><para>Configure the hardware watchdog device that the
         runtime and shutdown watchdog timers will open and use. Defaults
-        to <filename>/dev/watchdog</filename>. This setting has no
+        to <filename>/dev/watchdog0</filename>. This setting has no
         effect if a hardware watchdog is not available.</para></listitem>
       </varlistentry>
 
index bf5e705f830e0c5b66c8a7ab0d52654ecddf0f40..3c9ee6788f0066f6d808e0642d5c5b9195aa2210 100644 (file)
@@ -17,7 +17,7 @@
 
   <refnamediv>
     <refname>systemd-veritysetup-generator</refname>
-    <refpurpose>Unit generator for integrity protected block devices</refpurpose>
+    <refpurpose>Unit generator for verity protected block devices</refpurpose>
   </refnamediv>
 
   <refsynopsisdiv>
@@ -28,7 +28,7 @@
     <title>Description</title>
 
     <para><filename>systemd-veritysetup-generator</filename> is a generator that translates kernel command line options
-    configuring integrity-protected block devices (verity) into native systemd units early at boot and when
+    configuring verity protected block devices into native systemd units early at boot and when
     configuration of the system manager is reloaded. This will create
     <citerefentry><refentrytitle>systemd-veritysetup@.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>
     units as necessary.</para>
@@ -66,7 +66,7 @@
         data devices to use are automatically derived from the specified hash value. Specifically, the data partition
         device is looked for under a GPT partition UUID derived from the first 128bit of the root hash, the hash
         partition device is looked for under a GPT partition UUID derived from the last 128bit of the root hash. Hence
-        it is usually sufficient to specify the root hash to boot from an integrity protected root file system, as
+        it is usually sufficient to specify the root hash to boot from a verity protected root file system, as
         device paths are automatically determined from it â€” as long as the partition table is properly set up.</para>
         </listitem>
       </varlistentry>
@@ -76,7 +76,7 @@
         <term><varname>systemd.verity_root_hash=</varname></term>
 
         <listitem><para>These two settings take block device paths as arguments and may be used to explicitly
-        configure the data partition and hash partition to use for setting up the integrity protection for the root file
+        configure the data partition and hash partition to use for setting up the verity protection for the root file
         system. If not specified, these paths are automatically derived from the <varname>roothash=</varname> argument
         (see above).</para></listitem>
       </varlistentry>
index 70f08374e228a963297640ee6c1a04d8c88f7727..0f21c2fbbfd897524024ef76ce2be1f924cec4ec 100644 (file)
@@ -18,7 +18,7 @@
   <refnamediv>
     <refname>systemd-veritysetup@.service</refname>
     <refname>systemd-veritysetup</refname>
-    <refpurpose>Disk integrity protection logic</refpurpose>
+    <refpurpose>Disk verity protection logic</refpurpose>
   </refnamediv>
 
   <refsynopsisdiv>
   <refsect1>
     <title>Description</title>
 
-    <para><filename>systemd-veritysetup@.service</filename> is a service responsible for setting up integrity
-    protection (verity) block devices. It should be instantiated for each device that requires integrity
+    <para><filename>systemd-veritysetup@.service</filename> is a service responsible for setting up verity
+    protection block devices. It should be instantiated for each device that requires verity
     protection.</para>
 
     <para>At early boot and when the system manager configuration is reloaded kernel command line configuration for
-    integrity protected block devices is translated into <filename>systemd-veritysetup@.service</filename> units by
+    verity protected block devices is translated into <filename>systemd-veritysetup@.service</filename> units by
     <citerefentry><refentrytitle>systemd-veritysetup-generator</refentrytitle><manvolnum>8</manvolnum></citerefentry>.</para>
 
     <para><filename>systemd-veritysetup@.service</filename> calls <command>systemd-veritysetup</command>.</para>
index 77ed77918cf6273933a50fcec09acef368715c2a..bcc86417c69be294a115a22db5a1d063901684b3 100644 (file)
@@ -2100,19 +2100,6 @@ Table=1234</programlisting></para>
             <literal>information-request</literal>. Defaults to unset.</para>
           </listitem>
         </varlistentry>
-
-        <varlistentry>
-          <term><varname>RapidCommit=</varname></term>
-          <listitem>
-            <para>Takes a boolean. The DHCPv6 client can obtain configuration parameters from a DHCPv6 server through
-            a rapid two-message exchange (solicit and reply). When the rapid commit option is enabled by both
-            the DHCPv6 client and the DHCPv6 server, the two-message exchange is used, rather than the default
-            four-message exchange (solicit, advertise, request, and reply). The two-message exchange provides
-            faster client configuration and is beneficial in environments in which networks are under a heavy load.
-            See <ulink url="https://tools.ietf.org/html/rfc3315#section-17.2.1">RFC 3315</ulink> for details.
-            Defaults to true.</para>
-          </listitem>
-        </varlistentry>
       </variablelist>
   </refsect1>
 
@@ -2676,9 +2663,9 @@ Token=prefixstable:2002:da8:1::</programlisting></para>
       <varlistentry>
         <term><varname>DNSLifetimeSec=</varname></term>
 
-        <listitem><para>Lifetime in seconds for the DNS server addresses listed
-        in <varname>DNS=</varname> and search domains listed in
-        <varname>Domains=</varname>.</para></listitem>
+        <listitem><para>Lifetime in seconds for the DNS server addresses listed in
+        <varname>DNS=</varname> and search domains listed in <varname>Domains=</varname>. Defaults to
+        604800 seconds (one week).</para></listitem>
       </varlistentry>
 
     </variablelist>
index 8755b523ae2b7204c1a4bacb650799d41453bffc..9eb0b4a2c2b9c4e4f3dd9bbaab3cc80fdec1694e 100644 (file)
@@ -48,6 +48,8 @@
     <filename>initrd-root-device.target</filename>,
     <filename>initrd-root-fs.target</filename>,
     <filename>initrd-usr-fs.target</filename>,
+    <filename>integritysetup-pre.target</filename>,
+    <filename>integritysetup.target</filename>,
     <filename>kbrequest.target</filename>,
     <filename>kexec.target</filename>,
     <filename>local-fs-pre.target</filename>,
index d29e9f5f2d0806cfba24b5c9e8c4e2ff3e532c89..28dce1fe38295d211abbbaa72ca5bb513511b4f3 100644 (file)
@@ -33,12 +33,12 @@ This is based on crypttab(5).
     <title>Description</title>
 
     <para>The <filename>/etc/veritytab</filename> file describes
-    verity integrity protected block devices that are set up during
+    verity protected block devices that are set up during
     system boot.</para>
 
     <para>Empty lines and lines starting with the <literal>#</literal>
     character are ignored. Each of the remaining lines describes one
-    verity integrity protected block device. Fields are delimited by
+    verity protected block device. Fields are delimited by
     white space.</para>
 
     <para>Each line is in the form<programlisting><replaceable>volume-name</replaceable> <replaceable>data-device</replaceable> <replaceable>hash-device</replaceable> <replaceable>roothash</replaceable> <replaceable>options</replaceable></programlisting>
@@ -65,7 +65,7 @@ This is based on crypttab(5).
         <term><option>restart-on-corruption</option></term>
         <term><option>panic-on-corruption</option></term>
 
-        <listitem><para>Defines what to do if data integrity problem is detected (data corruption). Without these
+        <listitem><para>Defines what to do if a data verity problem is detected (data corruption). Without these
         options kernel fails the IO operation with I/O error. With <literal>--ignore-corruption</literal> option the
         corruption is only logged. With <literal>--restart-on-corruption</literal> or
         <literal>--panic-on-corruption</literal> the kernel is restarted (panicked) immediately.
@@ -149,18 +149,18 @@ This is based on crypttab(5).
       <varlistentry>
         <term><option>x-initrd.attach</option></term>
 
-        <listitem><para>Setup this verity integrity protected block device in the initramfs, similarly to
+        <listitem><para>Setup this verity protected block device in the initramfs, similarly to
         <citerefentry><refentrytitle>systemd.mount</refentrytitle><manvolnum>5</manvolnum></citerefentry>
         units marked with <option>x-initrd.mount</option>.</para>
 
         <para>Although it's not necessary to mark the mount entry for the root file system with
         <option>x-initrd.mount</option>, <option>x-initrd.attach</option> is still recommended with
-        the verity integrity protected block device containing the root file system as otherwise systemd
+        the verity protected block device containing the root file system as otherwise systemd
         will attempt to detach the device during the regular system shutdown while it's still in
         use. With this option the device will still be detached but later after the root file
         system is unmounted.</para>
 
-        <para>All other verity integrity protected block devices that contain file systems mounted in the
+        <para>All other verity protected block devices that contain file systems mounted in the
         initramfs should use this option.</para>
         </listitem>
       </varlistentry>
@@ -176,7 +176,7 @@ This is based on crypttab(5).
     <title>Examples</title>
     <example>
       <title>/etc/veritytab example</title>
-      <para>Set up two verity integrity protected block devices. One using device blocks, another using files.</para>
+      <para>Set up two verity protected block devices. One using device blocks, another using files.</para>
 
       <programlisting>usr  PARTUUID=783e45ae-7aa3-484a-beef-a80ff9c19cbb PARTUUID=21dc1dfe-4c33-8b48-98a9-918a22eb3e37 36e3f740ad502e2c25e2a23d9c7c17bf0fdad2300b7580842d4b7ec1fb0fa263 auto
 data /etc/data /etc/hash a5ee4b42f70ae1f46a08a7c92c2e0a20672ad2f514792730f5d49d7606ab8fdf auto
index 7d97ba2fe935a0380a7fd40ec4abbb821e8f0f11..f1be04e5aea7124f4b019be109db8e527f3f9af1 100644 (file)
@@ -252,6 +252,7 @@ conf.set_quoted('SYSTEMD_GROWFS_PATH',                        rootlibexecdir / '
 conf.set_quoted('SYSTEMD_HOMEWORK_PATH',                      rootlibexecdir / 'systemd-homework')
 conf.set_quoted('SYSTEMD_IMPORT_FS_PATH',                     rootlibexecdir / 'systemd-import-fs')
 conf.set_quoted('SYSTEMD_IMPORT_PATH',                        rootlibexecdir / 'systemd-import')
+conf.set_quoted('SYSTEMD_INTEGRITYSETUP_PATH',                rootlibexecdir / 'systemd-integritysetup')
 conf.set_quoted('SYSTEMD_KBD_MODEL_MAP',                      pkgdatadir / 'kbd-model-map')
 conf.set_quoted('SYSTEMD_LANGUAGE_FALLBACK_MAP',              pkgdatadir / 'language-fallback-map')
 conf.set_quoted('SYSTEMD_MAKEFS_PATH',                        rootlibexecdir / 'systemd-makefs')
@@ -546,6 +547,7 @@ foreach ident : [
         ['mount_setattr',     '''#include <sys/mount.h>'''],
         ['move_mount',        '''#include <sys/mount.h>'''],
         ['open_tree',         '''#include <sys/mount.h>'''],
+        ['getdents64',        '''#include <dirent.h>'''],
 ]
 
         have = cc.has_function(ident[0], prefix : ident[1], args : '-D_GNU_SOURCE')
@@ -2534,6 +2536,25 @@ if conf.get('HAVE_LIBCRYPTSETUP') == 1
                                 libp11kit],
                 install_rpath : rootlibexecdir,
                 install : true)
+
+        executable(
+                'systemd-integritysetup',
+                ['src/integritysetup/integritysetup.c', 'src/integritysetup/integrity-util.c'],
+                include_directories : includes,
+                link_with : [libshared],
+                dependencies : [libcryptsetup],
+                install_rpath : rootlibexecdir,
+                install : true,
+                install_dir : rootlibexecdir)
+
+        executable(
+                'systemd-integritysetup-generator',
+                ['src/integritysetup/integritysetup-generator.c', 'src/integritysetup/integrity-util.c'],
+                include_directories : includes,
+                link_with : [libshared],
+                install_rpath : rootlibexecdir,
+                install : true,
+                install_dir : systemgeneratordir)
 endif
 
 if conf.get('HAVE_SYSV_COMPAT') == 1
@@ -2597,18 +2618,17 @@ endif
 
 if conf.get('ENABLE_LOCALED') == 1
         if conf.get('HAVE_XKBCOMMON') == 1
-                # logind will load libxkbcommon.so dynamically on its own
-                deps = [libdl]
-                extra_includes = [libxkbcommon.get_pkgconfig_variable('includedir')]
+                # logind will load libxkbcommon.so dynamically on its own, but we still
+                # need to specify where the headers are
+                deps = [libdl, libxkbcommon.partial_dependency(compile_args: true)]
         else
                 deps = []
-                extra_includes = []
         endif
 
         executable(
                 'systemd-localed',
                 systemd_localed_sources,
-                include_directories : includes + extra_includes,
+                include_directories : includes,
                 link_with : [libshared],
                 dependencies : deps,
                 install_rpath : rootlibexecdir,
diff --git a/po/.gitattributes b/po/.gitattributes
new file mode 100644 (file)
index 0000000..9418c2a
--- /dev/null
@@ -0,0 +1 @@
+/LINGUAS  generated
index 22a21a1bf6af61aeede4ba782370de0e59e90683..e63f739f2d0ba673735c846da474ed46ce061224 100644 (file)
@@ -1,5 +1,6 @@
 src/boot/efi/boot.c
 src/boot/efi/secure-boot.c
+src/boot/efi/stub.c
 src/core/dbus-automount.c
 src/core/dbus-device.c
 src/core/dbus-job.c
index e61188fee94047126a62a12f0caac7a75ef207a8..190e3d33f5eac988ae88c93f4cd005c8ff1c5d91 100644 (file)
@@ -57,7 +57,7 @@ _bootctl() {
 
     local -A VERBS=(
         # systemd-efi-options takes an argument, but it is free-form, so we cannot complete it
-        [STANDALONE]='help status install update remove is-installed random-seed systemd-efi-options list'
+        [STANDALONE]='help status install update remove is-installed random-seed systemd-efi-options list set-timeout set-timeout-oneshot'
         [BOOTENTRY]='set-default set-oneshot'
         [BOOLEAN]='reboot-to-firmware'
     )
index 2b50f307f1f458139d693759c149ceef4b720b13..87ecbe37c3fd4de63dd90c9457f808c01fc1966c 100644 (file)
@@ -46,6 +46,8 @@ _bootctl_reboot-to-firmware() {
         "list:List boot loader entries"
         "set-default:Set the default boot loader entry"
         "set-oneshot:Set the default boot loader entry only for the next boot"
+        "set-timeout:Set the menu timeout"
+        "set-timeout-oneshot:Set the menu timeout for the next boot only"
     )
     if (( CURRENT == 1 )); then
         _describe -t commands 'bootctl command' _bootctl_cmds || compadd "$@"
index 6fcf58466752385bd3eeb77eb09658951cae6ec6..fd92135fc7541ab96f5e841d5e3a801ac6367d26 100644 (file)
@@ -387,7 +387,7 @@ static int run(int argc, char *argv[]) {
         if (!sysname)
                 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Requires a subsystem and sysname pair specifying a backlight device.");
 
-        ss = strndupa(argv[2], sysname - argv[2]);
+        ss = strndupa_safe(argv[2], sysname - argv[2]);
 
         sysname++;
 
index e587fe79e7a90903fc4fa477b5ca04351d4b8912..65d517561931f08883ddccfadaec27c922ede4f1 100644 (file)
@@ -22,20 +22,25 @@ typedef void (*free_func_t)(void *p);
 
 #define new0(t, n) ((t*) calloc((n) ?: 1, sizeof(t)))
 
+#define alloca_safe(n)                                                  \
+        ({                                                              \
+                size_t _nn_ = n;                                        \
+                assert(_nn_ <= ALLOCA_MAX);                             \
+                alloca(_nn_ == 0 ? 1 : _nn_);                           \
+        })                                                              \
+
 #define newa(t, n)                                                      \
         ({                                                              \
                 size_t _n_ = n;                                         \
                 assert(!size_multiply_overflow(sizeof(t), _n_));        \
-                assert(sizeof(t)*_n_ <= ALLOCA_MAX);                    \
-                (t*) alloca((sizeof(t)*_n_) ?: 1);                      \
+                (t*) alloca_safe(sizeof(t)*_n_);                        \
         })
 
 #define newa0(t, n)                                                     \
         ({                                                              \
                 size_t _n_ = n;                                         \
                 assert(!size_multiply_overflow(sizeof(t), _n_));        \
-                assert(sizeof(t)*_n_ <= ALLOCA_MAX);                    \
-                (t*) alloca0((sizeof(t)*_n_) ?: 1);                     \
+                (t*) alloca0((sizeof(t)*_n_));                          \
         })
 
 #define newdup(t, p, n) ((t*) memdup_multiply(p, sizeof(t), (n)))
@@ -44,12 +49,6 @@ typedef void (*free_func_t)(void *p);
 
 #define malloc0(n) (calloc(1, (n) ?: 1))
 
-#define mfree(memory)                           \
-        ({                                      \
-                free(memory);                   \
-                (typeof(memory)) NULL;          \
-        })
-
 #define free_and_replace(a, b)                  \
         ({                                      \
                 typeof(a)* _a = &(a);           \
@@ -67,8 +66,7 @@ void* memdup_suffix0(const void *p, size_t l); /* We can't use _alloc_() here, s
         ({                                      \
                 void *_q_;                      \
                 size_t _l_ = l;                 \
-                assert(_l_ <= ALLOCA_MAX);      \
-                _q_ = alloca(_l_ ?: 1);         \
+                _q_ = alloca_safe(_l_);         \
                 memcpy_safe(_q_, p, _l_);       \
         })
 
@@ -76,8 +74,7 @@ void* memdup_suffix0(const void *p, size_t l); /* We can't use _alloc_() here, s
         ({                                      \
                 void *_q_;                      \
                 size_t _l_ = l;                 \
-                assert(_l_ <= ALLOCA_MAX);      \
-                _q_ = alloca(_l_ + 1);          \
+                _q_ = alloca_safe(_l_ + 1);     \
                 ((uint8_t*) _q_)[_l_] = 0;      \
                 memcpy_safe(_q_, p, _l_);       \
         })
@@ -144,9 +141,8 @@ void* greedy_realloc0(void **p, size_t need, size_t size);
         ({                                              \
                 char *_new_;                            \
                 size_t _len_ = n;                       \
-                assert(_len_ <= ALLOCA_MAX);            \
-                _new_ = alloca(_len_ ?: 1);             \
-                (void *) memset(_new_, 0, _len_);       \
+                _new_ = alloca_safe(_len_);             \
+                memset(_new_, 0, _len_);                \
         })
 
 /* It's not clear what alignment glibc/gcc alloca() guarantee, hence provide a guaranteed safe version */
@@ -155,8 +151,7 @@ void* greedy_realloc0(void **p, size_t need, size_t size);
                 void *_ptr_;                                            \
                 size_t _mask_ = (align) - 1;                            \
                 size_t _size_ = size;                                   \
-                assert(_size_ <= ALLOCA_MAX);                           \
-                _ptr_ = alloca((_size_ + _mask_) ?: 1);                 \
+                _ptr_ = alloca_safe(_size_ + _mask_);                   \
                 (void*)(((uintptr_t)_ptr_ + _mask_) & ~_mask_);         \
         })
 
@@ -165,7 +160,7 @@ void* greedy_realloc0(void **p, size_t need, size_t size);
                 void *_new_;                                            \
                 size_t _xsize_ = (size);                                \
                 _new_ = alloca_align(_xsize_, (align));                 \
-                (void*)memset(_new_, 0, _xsize_);                       \
+                memset(_new_, 0, _xsize_);                              \
         })
 
 #if HAS_FEATURE_MEMORY_SANITIZER
@@ -193,3 +188,19 @@ void* greedy_realloc0(void **p, size_t need, size_t size);
                 __builtin_types_compatible_p(typeof(x), typeof(&*(x))), \
                 MALLOC_SIZEOF_SAFE(x)/sizeof((x)[0]),                   \
                 VOID_0))
+
+
+/* These are like strdupa()/strndupa(), but honour ALLOCA_MAX */
+#define strdupa_safe(s)                                                 \
+        ({                                                              \
+                const char *_t = (s);                                   \
+                (char*) memdupa_suffix0(_t, strlen(_t));                \
+        })
+
+#define strndupa_safe(s, n)                                             \
+        ({                                                              \
+                const char *_t = (s);                                   \
+                (char*) memdupa_suffix0(_t, strnlen(_t, (n)));          \
+        })
+
+#include "memory-util.h"
index 37a5a530f350d36b20bc9b5e9612f92c6de9e7a7..e5f38c65d04883276def09f10347efbd09d8a3f8 100644 (file)
@@ -1131,7 +1131,7 @@ int cg_path_decode_unit(const char *cgroup, char **unit) {
         if (n < 3)
                 return -ENXIO;
 
-        c = strndupa(cgroup, n);
+        c = strndupa_safe(cgroup, n);
         c = cg_unescape(c);
 
         if (!unit_name_is_valid(c, UNIT_NAME_PLAIN|UNIT_NAME_INSTANCE))
index bc979915b5bf30da042adbf478180f985c98aad4..27bbba4e4bf184684875dc9274f4d838071b202a 100644 (file)
@@ -394,7 +394,7 @@ int strv_env_replace_consume(char ***l, char *p) {
                 return -EINVAL;
         }
 
-        name = strndupa(p, t - p);
+        name = strndupa_safe(p, t - p);
 
         STRV_FOREACH(f, *l)
                 if (env_entry_has_name(*f, name)) {
@@ -481,7 +481,7 @@ char *strv_env_get_n(char **l, const char *name, size_t k, unsigned flags) {
         if (flags & REPLACE_ENV_USE_ENVIRONMENT) {
                 const char *t;
 
-                t = strndupa(name, k);
+                t = strndupa_safe(name, k);
                 return getenv(t);
         };
 
@@ -804,7 +804,7 @@ int putenv_dup(const char *assignment, bool override) {
         if (!e)
                 return -EINVAL;
 
-        n = strndupa(assignment, e - assignment);
+        n = strndupa_safe(assignment, e - assignment);
 
         /* This is like putenv(), but uses setenv() so that our memory doesn't become part of environ[]. */
         if (setenv(n, e + 1, override) < 0)
index 0a483854f2a4ab62dd7e20002314922f2eb74a75..09c72830c26aca518bafa46aff6a31660a0958c8 100644 (file)
@@ -547,12 +547,25 @@ int read_virtual_file_fd(int fd, size_t max_size, char **ret_contents, size_t *r
         return !truncated;
 }
 
-int read_virtual_file(const char *filename, size_t max_size, char **ret_contents, size_t *ret_size) {
+int read_virtual_file_at(
+                int dir_fd,
+                const char *filename,
+                size_t max_size,
+                char **ret_contents,
+                size_t *ret_size) {
+
         _cleanup_close_ int fd = -1;
 
-        assert(filename);
+        assert(dir_fd >= 0 || dir_fd == AT_FDCWD);
+
+        if (!filename) {
+                if (dir_fd == AT_FDCWD)
+                        return -EBADF;
+
+                return read_virtual_file_fd(dir_fd, max_size, ret_contents, ret_size);
+        }
 
-        fd = open(filename, O_RDONLY | O_NOCTTY | O_CLOEXEC);
+        fd = openat(dir_fd, filename, O_RDONLY | O_NOCTTY | O_CLOEXEC);
         if (fd < 0)
                 return -errno;
 
index 899def946bd4c4c8ce14b49ca287d10ffab83425..cea3dd893d1f3d10f81f1436027618c4c5000436 100644 (file)
@@ -69,7 +69,10 @@ static inline int read_full_file(const char *filename, char **ret_contents, size
 }
 
 int read_virtual_file_fd(int fd, size_t max_size, char **ret_contents, size_t *ret_size);
-int read_virtual_file(const char *filename, size_t max_size, char **ret_contents, size_t *ret_size);
+int read_virtual_file_at(int dir_fd, const char *filename, size_t max_size, char **ret_contents, size_t *ret_size);
+static inline int read_virtual_file(const char *filename, size_t max_size, char **ret_contents, size_t *ret_size) {
+        return read_virtual_file_at(AT_FDCWD, filename, max_size, ret_contents, ret_size);
+}
 static inline int read_full_virtual_file(const char *filename, char **ret_contents, size_t *ret_size) {
         return read_virtual_file(filename, SIZE_MAX, ret_contents, ret_size);
 }
index 847ebd1841dcced70edab6ee123898374fff0c90..a60ac240ec8bd0514f185e6ede3d23a74af0f3e1 100644 (file)
@@ -56,7 +56,7 @@ int rmdir_parents(const char *path, const char *stop) {
         if (!path_is_safe(stop))
                 return -EINVAL;
 
-        p = strdupa(path);
+        p = strdupa_safe(path);
 
         for (;;) {
                 char *slash = NULL;
index 5fd2c5dcb4d3f755d529b95d7242cd4dc8d47361..983e5bc69c4511cc14705d57e8f6fbfc4b2e2fbf 100644 (file)
@@ -1073,8 +1073,10 @@ int log_struct_iovec_internal(
 
         for (size_t i = 0; i < n_input_iovec; i++)
                 if (memory_startswith(input_iovec[i].iov_base, input_iovec[i].iov_len, "MESSAGE=")) {
-                        char *m = strndupa(input_iovec[i].iov_base + STRLEN("MESSAGE="),
-                                           input_iovec[i].iov_len - STRLEN("MESSAGE="));
+                        char *m;
+
+                        m = strndupa_safe((char*) input_iovec[i].iov_base + STRLEN("MESSAGE="),
+                                          input_iovec[i].iov_len - STRLEN("MESSAGE="));
 
                         return log_dispatch_internal(level, error, file, line, func, NULL, NULL, NULL, NULL, m);
                 }
index 6d5840a832d9c466d86e35c9e75347aed9984d0d..c05339832d7171fcedcb2f9959be34eb2dcce1c5 100644 (file)
@@ -25,7 +25,7 @@
 #define _public_ __attribute__((__visibility__("default")))
 #define _hidden_ __attribute__((__visibility__("hidden")))
 #define _weakref_(x) __attribute__((__weakref__(#x)))
-#define _alignas_(x) __attribute__((__aligned__(__alignof(x))))
+#define _alignas_(x) __attribute__((__aligned__(__alignof__(x))))
 #define _alignptr_ __attribute__((__aligned__(sizeof(void*))))
 #define _warn_unused_result_ __attribute__((__warn_unused_result__))
 
index 57dae77b5357d7b62039f307b3dca919faa399a1..5e80fa79fd0bf97e8318865930cc9bb2f27a9a06 100644 (file)
@@ -540,3 +540,19 @@ static inline int missing_move_mount(
 
 #  define move_mount missing_move_mount
 #endif
+
+/* ======================================================================= */
+
+#if !HAVE_GETDENTS64
+
+static inline ssize_t missing_getdents64(int fd, void *buffer, size_t length) {
+#  if defined __NR_getdents64 && __NR_getdents64 >= 0
+        return syscall(__NR_getdents64, fd, buffer, length);
+#  else
+        errno = ENOSYS;
+        return -1;
+#  endif
+}
+
+#  define getdents64 missing_getdents64
+#endif
index 60d08a9493bdfbbc0d6de0fdd48fceb001582e5d..bd9cb76ddf0d9f3c7cc6ebd618a515eda3ede316 100644 (file)
@@ -126,7 +126,7 @@ int mkdir_parents_internal(const char *prefix, const char *path, mode_t mode, ui
         assert(*e == '/');
 
         /* drop the last component */
-        path = strndupa(path, e - path);
+        path = strndupa_safe(path, e - path);
         r = is_dir(path, true);
         if (r > 0)
                 return 0;
index 783f94b2f702729fb8ec42f0932469b6469d53f6..52a429f1bde81a28c3bed7f64858cb7281d5cea1 100644 (file)
@@ -156,7 +156,7 @@ static bool filename_possibly_with_slash_suffix(const char *s) {
         if (slash[strspn(slash, "/")] != 0) /* Check that the suffix consist only of one or more slashes */
                 return false;
 
-        copied = strndupa(s, slash - s);
+        copied = strndupa_safe(s, slash - s);
         return filename_is_valid(copied);
 }
 
index 27b1b84affeebb132ee22fa174f8405dfac48bf6..d03a6eeb05e593062abfa083b5f7bcfbe11f7fdc 100644 (file)
@@ -704,7 +704,7 @@ int parse_dev(const char *s, dev_t *ret) {
         if (s[n] != ':')
                 return -EINVAL;
 
-        major = strndupa(s, n);
+        major = strndupa_safe(s, n);
         r = safe_atou(major, &x);
         if (r < 0)
                 return r;
@@ -765,7 +765,7 @@ int parse_loadavg_fixed_point(const char *s, loadavg_t *ret) {
         if (!d)
                 return -EINVAL;
 
-        i_str = strndupa(s, d - s);
+        i_str = strndupa_safe(s, d - s);
         f_str = d + 1;
 
         r = safe_atolu_full(i_str, 10, &i);
index 987834b0d55ac1929d8b1b4a18ac9fb84d94cca7..1969aa988239715926ae39bb6982da24d3c0bbbd 100644 (file)
@@ -489,7 +489,7 @@ static int get_paths_from_environ(const char *var, char ***paths, bool *append)
 
                 k = endswith(e, ":");
                 if (k) {
-                        e = strndupa(e, k - e);
+                        e = strndupa_safe(e, k - e);
                         *append = true;
                 }
 
index 06f20fd61e9ab239b7c952046055a1ce20c1a4b6..cab9d0eaeac055e889adb75441b95c4aed8e2606 100644 (file)
@@ -12,7 +12,7 @@ static int parse_parts_value_whole(const char *p, const char *symbol) {
         if (!pc)
                 return -EINVAL;
 
-        n = strndupa(p, pc - p);
+        n = strndupa_safe(p, pc - p);
         r = safe_atoi(n, &v);
         if (r < 0)
                 return r;
@@ -37,10 +37,10 @@ static int parse_parts_value_with_tenths_place(const char *p, const char *symbol
                 if (dot[1] < '0' || dot[1] > '9')
                         return -EINVAL;
                 q = dot[1] - '0';
-                n = strndupa(p, dot - p);
+                n = strndupa_safe(p, dot - p);
         } else {
                 q = 0;
-                n = strndupa(p, pc - p);
+                n = strndupa_safe(p, pc - p);
         }
         r = safe_atoi(n, &v);
         if (r < 0)
@@ -81,10 +81,10 @@ static int parse_parts_value_with_hundredths_place(const char *p, const char *sy
                         /* We do not support zero or more than two places */
                         return -EINVAL;
 
-                n = strndupa(p, dot - p);
+                n = strndupa_safe(p, dot - p);
         } else {
                 q = 0;
-                n = strndupa(p, pc - p);
+                n = strndupa_safe(p, pc - p);
         }
         r = safe_atoi(n, &v);
         if (r < 0)
index f076ad097ea4d0f6d9e9c7727f8d922a91d71dec..688c0004eac5980fd40549ce0f5b25570afedfb9 100644 (file)
@@ -135,7 +135,7 @@ int procfs_tasks_get_current(uint64_t *ret) {
 
         p++;
         n = strspn(p, DIGITS);
-        nr = strndupa(p, n);
+        nr = strndupa_safe(p, n);
 
         return safe_atou64(nr, ret);
 }
index 2aabbccadb948c015dd83606c24999e055f11346..309e92118541f44f452e22ffbc09d2d1b99b5a41 100644 (file)
@@ -4,6 +4,7 @@
 #include "dirent-util.h"
 #include "fd-util.h"
 #include "fileio.h"
+#include "missing_syscall.h"
 #include "mountpoint-util.h"
 #include "recurse-dir.h"
 #include "sort-util.h"
@@ -14,76 +15,130 @@ static int sort_func(struct dirent * const *a, struct dirent * const *b) {
         return strcmp((*a)->d_name, (*b)->d_name);
 }
 
-struct dirent** readdir_all_free(struct dirent **array) {
+static bool ignore_dirent(const struct dirent *de, RecurseDirFlags flags) {
+        assert(de);
 
-        /* Destructor that relies on the fact that the array of dirent structure pointers is NULL
-         * terminated */
+        /* Depending on flag either ignore everything starting with ".", or just "." itself and ".." */
 
-        if (!array)
-                return NULL;
-
-        for (struct dirent **i = array; *i; i++)
-                free(*i);
-
-        return mfree(array);
+        return FLAGS_SET(flags, RECURSE_DIR_IGNORE_DOT) ?
+                de->d_name[0] == '.' :
+                dot_or_dot_dot(de->d_name);
 }
 
-int readdir_all(DIR *d,
+/* Maximum space one direent structure might require at most */
+#define DIRENT_SIZE_MAX MAX(sizeof(struct dirent), offsetof(struct dirent, d_name) + NAME_MAX + 1)
+
+int readdir_all(int dir_fd,
                 RecurseDirFlags flags,
-                struct dirent ***ret) {
+                DirectoryEntries **ret) {
 
-        _cleanup_(readdir_all_freep) struct dirent **de_array = NULL;
-        size_t n_de = 0;
+        _cleanup_free_ DirectoryEntries *de = NULL;
+        DirectoryEntries *nde;
+        size_t add, sz, j;
 
-        assert(d);
+        assert(dir_fd >= 0);
 
         /* Returns an array with pointers to "struct dirent" directory entries, optionally sorted. Free the
          * array with readdir_all_freep(). */
 
+        /* Only if 64bit off_t is enabled struct dirent + struct dirent64 are actually the same. We require
+         * this, and we want them to be interchangable, hence verify that. */
+        assert_cc(_FILE_OFFSET_BITS == 64);
+        assert_cc(sizeof(struct dirent) == sizeof(struct dirent64));
+        assert_cc(offsetof(struct dirent, d_ino) == offsetof(struct dirent64, d_ino));
+        assert_cc(sizeof(((struct dirent*) NULL)->d_ino) == sizeof(((struct dirent64*) NULL)->d_ino));
+        assert_cc(offsetof(struct dirent, d_off) == offsetof(struct dirent64, d_off));
+        assert_cc(sizeof(((struct dirent*) NULL)->d_off) == sizeof(((struct dirent64*) NULL)->d_off));
+        assert_cc(offsetof(struct dirent, d_reclen) == offsetof(struct dirent64, d_reclen));
+        assert_cc(sizeof(((struct dirent*) NULL)->d_reclen) == sizeof(((struct dirent64*) NULL)->d_reclen));
+        assert_cc(offsetof(struct dirent, d_type) == offsetof(struct dirent64, d_type));
+        assert_cc(sizeof(((struct dirent*) NULL)->d_type) == sizeof(((struct dirent64*) NULL)->d_type));
+        assert_cc(offsetof(struct dirent, d_name) == offsetof(struct dirent64, d_name));
+        assert_cc(sizeof(((struct dirent*) NULL)->d_name) == sizeof(((struct dirent64*) NULL)->d_name));
+
+        /* Start with space for up to 8 directory entries. We expect at least 2 ("." + ".."), hence hopefully
+         * 8 will cover most cases comprehensively. (Note that most likely a lot more entries will actually
+         * fit in the buffer, given we calculate maximum file name length here.) */
+        de = malloc(offsetof(DirectoryEntries, buffer) + DIRENT_SIZE_MAX * 8);
+        if (!de)
+                return -ENOMEM;
+
+        de->buffer_size = 0;
         for (;;) {
-                _cleanup_free_ struct dirent *copy = NULL;
-                struct dirent *de;
+                size_t bs;
+                ssize_t n;
 
-                errno = 0;
-                de = readdir(d);
-                if (!de) {
-                        if (errno == 0)
-                                break;
+                bs = MIN(MALLOC_SIZEOF_SAFE(de) - offsetof(DirectoryEntries, buffer), (size_t) SSIZE_MAX);
+                assert(bs > de->buffer_size);
 
+                n = getdents64(dir_fd, de->buffer + de->buffer_size, bs - de->buffer_size);
+                if (n < 0)
                         return -errno;
-                }
+                if (n == 0)
+                        break;
 
-                /* Depending on flag either ignore everything starting with ".", or just "." itself and ".." */
-                if (FLAGS_SET(flags, RECURSE_DIR_IGNORE_DOT) ?
-                    de->d_name[0] == '.' :
-                    dot_or_dot_dot(de->d_name))
+                de->buffer_size += n;
+
+                if (de->buffer_size < bs - DIRENT_SIZE_MAX) /* Still room for one more entry, then try to
+                                                             * fill it up without growing the structure. */
                         continue;
 
-                if (n_de >= INT_MAX) /* Make sure we can return the number as 'int' return value */
-                        return -ERANGE;
+                if (bs >= SSIZE_MAX - offsetof(DirectoryEntries, buffer))
+                        return -EFBIG;
+                bs = bs >= (SSIZE_MAX - offsetof(DirectoryEntries, buffer))/2 ? SSIZE_MAX - offsetof(DirectoryEntries, buffer) : bs * 2;
 
-                if (!GREEDY_REALLOC(de_array, n_de+2))
+                nde = realloc(de, bs);
+                if (!nde)
                         return -ENOMEM;
 
-                copy = memdup(de, de->d_reclen);
-                if (!copy)
-                        return -ENOMEM;
+                de = nde;
+        }
+
+        de->n_entries = 0;
+        for (struct dirent *entry = (struct dirent*) de->buffer;
+             (uint8_t*) entry < de->buffer + de->buffer_size;
+             entry = (struct dirent*) ((uint8_t*) entry + entry->d_reclen)) {
+
+                if (ignore_dirent(entry, flags))
+                        continue;
 
-                de_array[n_de++] = TAKE_PTR(copy);
-                de_array[n_de] = NULL; /* guarantee array remains NUL terminated */
+                de->n_entries++;
+        }
+
+        sz = ALIGN(offsetof(DirectoryEntries, buffer) + de->buffer_size);
+        add = sizeof(struct dirent*) * de->n_entries;
+        if (add > SIZE_MAX - add)
+                return -ENOMEM;
+
+        nde = realloc(de, sz + add);
+        if (!nde)
+                return -ENOMEM;
+
+        de = nde;
+        de->entries = (struct dirent**) ((uint8_t*) de + ALIGN(offsetof(DirectoryEntries, buffer) + de->buffer_size));
+
+        j = 0;
+        for (struct dirent *entry = (struct dirent*) de->buffer;
+             (uint8_t*) entry < de->buffer + de->buffer_size;
+             entry = (struct dirent*) ((uint8_t*) entry + entry->d_reclen)) {
+
+                if (ignore_dirent(entry, flags))
+                        continue;
+
+                de->entries[j++] = entry;
         }
 
         if (FLAGS_SET(flags, RECURSE_DIR_SORT))
-                typesafe_qsort(de_array, n_de, sort_func);
+                typesafe_qsort(de->entries, de->n_entries, sort_func);
 
         if (ret)
-                *ret = TAKE_PTR(de_array);
+                *ret = TAKE_PTR(de);
 
-        return (int) n_de;
+        return 0;
 }
 
 int recurse_dir(
-                DIR *d,
+                int dir_fd,
                 const char *path,
                 unsigned statx_mask,
                 unsigned n_depth_max,
@@ -91,51 +146,50 @@ int recurse_dir(
                 recurse_dir_func_t func,
                 void *userdata) {
 
-        _cleanup_(readdir_all_freep) struct dirent **de = NULL;
-        int r, n;
+        _cleanup_free_ DirectoryEntries *de = NULL;
+        int r;
 
-        assert(d);
+        assert(dir_fd >= 0);
         assert(func);
 
-        /* This is a lot like ftw()/nftw(), but a lot more modern, i.e. built around openat()/statx(), and
-         * under the assumption that fds are not as 'expensive' as they used to be. */
+        /* This is a lot like ftw()/nftw(), but a lot more modern, i.e. built around openat()/statx()/O_PATH,
+         * and under the assumption that fds are not as 'expensive' as they used to be. */
 
         if (n_depth_max == 0)
                 return -EOVERFLOW;
         if (n_depth_max == UINT_MAX) /* special marker for "default" */
                 n_depth_max = DEFAULT_RECURSION_MAX;
 
-        n = readdir_all(d, flags, &de);
-        if (n < 0)
-                return n;
+        r = readdir_all(dir_fd, flags, &de);
+        if (r < 0)
+                return r;
 
-        for (int i = 0; i < n; i++) {
+        for (size_t i = 0; i < de->n_entries; i++) {
+                _cleanup_close_ int inode_fd = -1, subdir_fd = -1;
                 _cleanup_free_ char *joined = NULL;
-                _cleanup_closedir_ DIR *subdir = NULL;
-                _cleanup_close_ int inode_fd = -1;
                 STRUCT_STATX_DEFINE(sx);
                 bool sx_valid = false;
                 const char *p;
 
                 /* For each directory entry we'll do one of the following:
                  *
-                 * 1) If the entry refers to a directory, we'll open it as O_DIRECTORY 'subdir' and then statx() the opened directory if requested
-                 * 2) Otherwise and RECURSE_DIR_INODE_FD is set we'll open O_PATH 'inode_fd' and then statx() the opened inode
-                 * 3) Otherwise we'll statx() the directory entry via the directory we are currently looking at
+                 * 1) If the entry refers to a directory, we'll open it as O_DIRECTORY 'subdir_fd' and then statx() the opened directory via that new fd (if requested)
+                 * 2) Otherwise, if RECURSE_DIR_INODE_FD is set we'll open it as O_PATH 'inode_fd' and then statx() the opened inode via that new fd (if requested)
+                 * 3) Otherwise, we'll statx() the directory entry via the directory fd we are currently looking at (if requested)
                  */
 
                 if (path) {
-                        joined = path_join(path, de[i]->d_name);
+                        joined = path_join(path, de->entries[i]->d_name);
                         if (!joined)
                                 return -ENOMEM;
 
                         p = joined;
                 } else
-                        p = de[i]->d_name;
+                        p = de->entries[i]->d_name;
 
-                if (IN_SET(de[i]->d_type, DT_UNKNOWN, DT_DIR)) {
-                        subdir = xopendirat(dirfd(d), de[i]->d_name, O_NOFOLLOW);
-                        if (!subdir) {
+                if (IN_SET(de->entries[i]->d_type, DT_UNKNOWN, DT_DIR)) {
+                        subdir_fd = openat(dir_fd, de->entries[i]->d_name, O_DIRECTORY|O_NOFOLLOW|O_CLOEXEC);
+                        if (subdir_fd < 0) {
                                 if (errno == ENOENT) /* Vanished by now, go for next file immediately */
                                         continue;
 
@@ -147,9 +201,9 @@ int recurse_dir(
 
                                         r = func(RECURSE_DIR_SKIP_OPEN_DIR_ERROR_BASE + errno,
                                                  p,
-                                                 dirfd(d),
+                                                 dir_fd,
                                                  -1,
-                                                 de[i],
+                                                 de->entries[i],
                                                  NULL,
                                                  userdata);
                                         if (r == RECURSE_DIR_LEAVE_DIRECTORY)
@@ -164,10 +218,10 @@ int recurse_dir(
 
                         } else {
                                 /* If we managed to get a DIR* off the inode, it's definitely a directory. */
-                                de[i]->d_type = DT_DIR;
+                                de->entries[i]->d_type = DT_DIR;
 
                                 if (statx_mask != 0 || (flags & RECURSE_DIR_SAME_MOUNT)) {
-                                        r = statx_fallback(dirfd(subdir), "", AT_EMPTY_PATH, statx_mask, &sx);
+                                        r = statx_fallback(subdir_fd, "", AT_EMPTY_PATH, statx_mask, &sx);
                                         if (r < 0)
                                                 return r;
 
@@ -176,12 +230,12 @@ int recurse_dir(
                         }
                 }
 
-                if (!subdir) {
+                if (subdir_fd < 0) {
                         /* It's not a subdirectory. */
 
                         if (flags & RECURSE_DIR_INODE_FD) {
 
-                                inode_fd = openat(dirfd(d), de[i]->d_name, O_PATH|O_NOFOLLOW|O_CLOEXEC);
+                                inode_fd = openat(dir_fd, de->entries[i]->d_name, O_PATH|O_NOFOLLOW|O_CLOEXEC);
                                 if (inode_fd < 0) {
                                         if (errno == ENOENT) /* Vanished by now, go for next file immediately */
                                                 continue;
@@ -192,9 +246,9 @@ int recurse_dir(
 
                                         r = func(RECURSE_DIR_SKIP_OPEN_INODE_ERROR_BASE + errno,
                                                  p,
-                                                 dirfd(d),
+                                                 dir_fd,
                                                  -1,
-                                                 de[i],
+                                                 de->entries[i],
                                                  NULL,
                                                  userdata);
                                         if (r == RECURSE_DIR_LEAVE_DIRECTORY)
@@ -222,16 +276,16 @@ int recurse_dir(
                                          * directory fd â€” which sould be riskless now that we pinned the
                                          * inode. */
 
-                                        subdir = xopendirat(AT_FDCWD, FORMAT_PROC_FD_PATH(inode_fd), 0);
-                                        if (!subdir)
+                                        subdir_fd = openat(AT_FDCWD, FORMAT_PROC_FD_PATH(inode_fd), O_DIRECTORY|O_CLOEXEC);
+                                        if (subdir_fd < 0)
                                                 return -errno;
 
                                         inode_fd = safe_close(inode_fd);
                                 }
 
-                        } else if (statx_mask != 0 || (de[i]->d_type == DT_UNKNOWN && (flags & RECURSE_DIR_ENSURE_TYPE))) {
+                        } else if (statx_mask != 0 || (de->entries[i]->d_type == DT_UNKNOWN && (flags & RECURSE_DIR_ENSURE_TYPE))) {
 
-                                r = statx_fallback(dirfd(d), de[i]->d_name, AT_SYMLINK_NOFOLLOW, statx_mask | STATX_TYPE, &sx);
+                                r = statx_fallback(dir_fd, de->entries[i]->d_name, AT_SYMLINK_NOFOLLOW, statx_mask | STATX_TYPE, &sx);
                                 if (r == -ENOENT) /* Vanished by now? Go for next file immediately */
                                         continue;
                                 if (r < 0) {
@@ -241,9 +295,9 @@ int recurse_dir(
 
                                         r = func(RECURSE_DIR_SKIP_STAT_INODE_ERROR_BASE + -r,
                                                  p,
-                                                 dirfd(d),
+                                                 dir_fd,
                                                  -1,
-                                                 de[i],
+                                                 de->entries[i],
                                                  NULL,
                                                  userdata);
                                         if (r == RECURSE_DIR_LEAVE_DIRECTORY)
@@ -271,9 +325,9 @@ int recurse_dir(
 
                                         r = func(RECURSE_DIR_SKIP_STAT_INODE_ERROR_BASE + EISDIR,
                                                  p,
-                                                 dirfd(d),
+                                                 dir_fd,
                                                  -1,
-                                                 de[i],
+                                                 de->entries[i],
                                                  NULL,
                                                  userdata);
                                         if (r == RECURSE_DIR_LEAVE_DIRECTORY)
@@ -289,22 +343,22 @@ int recurse_dir(
                 if (sx_valid) {
                         /* Copy over the data we acquired through statx() if we acquired any */
                         if (sx.stx_mask & STATX_TYPE) {
-                                assert(!!subdir == !!S_ISDIR(sx.stx_mode));
-                                de[i]->d_type = IFTODT(sx.stx_mode);
+                                assert((subdir_fd < 0) == !S_ISDIR(sx.stx_mode));
+                                de->entries[i]->d_type = IFTODT(sx.stx_mode);
                         }
 
                         if (sx.stx_mask & STATX_INO)
-                                de[i]->d_ino = sx.stx_ino;
+                                de->entries[i]->d_ino = sx.stx_ino;
                 }
 
-                if (subdir) {
+                if (subdir_fd >= 0) {
                         if (FLAGS_SET(flags, RECURSE_DIR_SAME_MOUNT)) {
                                 bool is_mount;
 
                                 if (sx_valid && FLAGS_SET(sx.stx_attributes_mask, STATX_ATTR_MOUNT_ROOT))
                                         is_mount = FLAGS_SET(sx.stx_attributes, STATX_ATTR_MOUNT_ROOT);
                                 else {
-                                        r = fd_is_mount_point(dirfd(d), de[i]->d_name, 0);
+                                        r = fd_is_mount_point(dir_fd, de->entries[i]->d_name, 0);
                                         if (r < 0)
                                                 log_debug_errno(r, "Failed to determine whether %s is a submount, assuming not: %m", p);
 
@@ -314,9 +368,9 @@ int recurse_dir(
                                 if (is_mount) {
                                         r = func(RECURSE_DIR_SKIP_MOUNT,
                                                  p,
-                                                 dirfd(d),
-                                                 dirfd(subdir),
-                                                 de[i],
+                                                 dir_fd,
+                                                 subdir_fd,
+                                                 de->entries[i],
                                                  statx_mask != 0 ? &sx : NULL, /* only pass sx if user asked for it */
                                                  userdata);
                                         if (r == RECURSE_DIR_LEAVE_DIRECTORY)
@@ -333,9 +387,9 @@ int recurse_dir(
 
                                 r = func(RECURSE_DIR_SKIP_DEPTH,
                                          p,
-                                         dirfd(d),
-                                         dirfd(subdir),
-                                         de[i],
+                                         dir_fd,
+                                         subdir_fd,
+                                         de->entries[i],
                                          statx_mask != 0 ? &sx : NULL, /* only pass sx if user asked for it */
                                          userdata);
                                 if (r == RECURSE_DIR_LEAVE_DIRECTORY)
@@ -348,9 +402,9 @@ int recurse_dir(
 
                         r = func(RECURSE_DIR_ENTER,
                                  p,
-                                 dirfd(d),
-                                 dirfd(subdir),
-                                 de[i],
+                                 dir_fd,
+                                 subdir_fd,
+                                 de->entries[i],
                                  statx_mask != 0 ? &sx : NULL, /* only pass sx if user asked for it */
                                  userdata);
                         if (r == RECURSE_DIR_LEAVE_DIRECTORY)
@@ -360,7 +414,7 @@ int recurse_dir(
                         if (r != RECURSE_DIR_CONTINUE)
                                 return r;
 
-                        r = recurse_dir(subdir,
+                        r = recurse_dir(subdir_fd,
                                         p,
                                         statx_mask,
                                         n_depth_max - 1,
@@ -372,18 +426,18 @@ int recurse_dir(
 
                         r = func(RECURSE_DIR_LEAVE,
                                  p,
-                                 dirfd(d),
-                                 dirfd(subdir),
-                                 de[i],
+                                 dir_fd,
+                                 subdir_fd,
+                                 de->entries[i],
                                  statx_mask != 0 ? &sx : NULL, /* only pass sx if user asked for it */
                                  userdata);
                 } else
                         /* Non-directory inode */
                         r = func(RECURSE_DIR_ENTRY,
                                  p,
-                                 dirfd(d),
+                                 dir_fd,
                                  inode_fd,
-                                 de[i],
+                                 de->entries[i],
                                  statx_mask != 0 ? &sx : NULL, /* only pass sx if user asked for it */
                                  userdata);
 
@@ -406,11 +460,17 @@ int recurse_dir_at(
                 recurse_dir_func_t func,
                 void *userdata) {
 
-        _cleanup_closedir_ DIR *d = NULL;
+        _cleanup_close_ int fd = -1;
+
+        assert(atfd >= 0 || atfd == AT_FDCWD);
+        assert(func);
+
+        if (!path)
+                path = ".";
 
-        d = xopendirat(atfd, path, 0);
-        if (!d)
+        fd = openat(atfd, path, O_DIRECTORY|O_CLOEXEC);
+        if (fd < 0)
                 return -errno;
 
-        return recurse_dir(d, path, statx_mask, n_depth_max, flags, func, userdata);
+        return recurse_dir(fd, path, statx_mask, n_depth_max, flags, func, userdata);
 }
index 0605884fc04c2d8f241eab143a9f3373914423c6..93b00f0d974323f6995aa2df928afd024508e612 100644 (file)
@@ -67,9 +67,14 @@ typedef enum RecurseDirFlags {
         RECURSE_DIR_INODE_FD     = 1 << 4,  /* passes an opened inode fd (O_DIRECTORY fd in case of dirs, O_PATH otherwise) */
 } RecurseDirFlags;
 
-struct dirent** readdir_all_free(struct dirent **array);
-DEFINE_TRIVIAL_CLEANUP_FUNC(struct dirent **, readdir_all_free);
-int readdir_all(DIR *d, RecurseDirFlags flags, struct dirent ***ret);
+typedef struct DirectoryEntries {
+        size_t n_entries;
+        struct dirent** entries;
+        size_t buffer_size;
+        uint8_t buffer[] _alignas_(struct dirent);
+} DirectoryEntries;
 
-int recurse_dir(DIR *d, const char *path, unsigned statx_mask, unsigned n_depth_max, RecurseDirFlags flags, recurse_dir_func_t func, void *userdata);
+int readdir_all(int dir_fd, RecurseDirFlags flags, DirectoryEntries **ret);
+
+int recurse_dir(int dir_fd, const char *path, unsigned statx_mask, unsigned n_depth_max, RecurseDirFlags flags, recurse_dir_func_t func, void *userdata);
 int recurse_dir_at(int atfd, const char *path, unsigned statx_mask, unsigned n_depth_max, RecurseDirFlags flags, recurse_dir_func_t func, void *userdata);
index 34b2b279189230a8247abd5db0ee1c62f48c6661..f945a96f0de0aeb63ca22166ab14a45a6a18465b 100644 (file)
@@ -119,7 +119,7 @@ int sigprocmask_many(int how, sigset_t *old, ...) {
         return 0;
 }
 
-static const char *const __signal_table[] = {
+static const char *const static_signal_table[] = {
         [SIGHUP] = "HUP",
         [SIGINT] = "INT",
         [SIGQUIT] = "QUIT",
@@ -155,13 +155,13 @@ static const char *const __signal_table[] = {
         [SIGSYS] = "SYS"
 };
 
-DEFINE_PRIVATE_STRING_TABLE_LOOKUP(__signal, int);
+DEFINE_PRIVATE_STRING_TABLE_LOOKUP(static_signal, int);
 
 const char *signal_to_string(int signo) {
         static thread_local char buf[STRLEN("RTMIN+") + DECIMAL_STR_MAX(int)];
         const char *name;
 
-        name = __signal_to_string(signo);
+        name = static_signal_to_string(signo);
         if (name)
                 return name;
 
@@ -190,7 +190,7 @@ int signal_from_string(const char *s) {
                 s += 3;
 
         /* Check that the input is a signal name. */
-        signo = __signal_from_string(s);
+        signo = static_signal_from_string(s);
         if (signo > 0)
                 return signo;
 
index 1e66f8700bcedff465a9604069b6609a0a4075f1..94ae90929a18c684b314561755f13a6ed00a8ea1 100644 (file)
@@ -551,7 +551,7 @@ int getpeername_pretty(int fd, bool include_port, char **ret) {
                 return -errno;
 
         if (sa.sa.sa_family == AF_UNIX) {
-                struct ucred ucred = {};
+                struct ucred ucred = UCRED_INVALID;
 
                 /* UNIX connection sockets are anonymous, so let's use
                  * PID/UID as pretty credentials instead */
index cb4a92236fa1fe9ed4701204bfd7645a892cc2e4..c4fafa084b7f06809a3f1944bf1ba601ebd6c603 100644 (file)
@@ -327,3 +327,6 @@ static inline int socket_set_recvfragsize(int fd, int af, bool b) {
 }
 
 int socket_get_mtu(int fd, int af, size_t *ret);
+
+/* an initializer for struct ucred that initialized all fields to the invalid value appropriate for each */
+#define UCRED_INVALID { .pid = 0, .uid = UID_INVALID, .gid = GID_INVALID }
index a9c68b7e3e394e4011827f0d99da39c3dcfd1645..e0fb9cf4a801bd1d1bdd14474d462f936a8d7493 100644 (file)
@@ -5,7 +5,7 @@
 
 /* hey glibc, APIs with callbacks without a user pointer are so useless */
 void *xbsearch_r(const void *key, const void *base, size_t nmemb, size_t size,
-                 __compar_d_fn_t compar, void *arg) {
+                 comparison_userdata_fn_t compar, void *arg) {
         size_t l, u, idx;
         const void *p;
         int comparison;
index 49586a4a24073f5599aa0ba28dd67d8b6b8a1518..02a6784d99d109d1956ca6019a21838255bead98 100644 (file)
@@ -5,14 +5,20 @@
 
 #include "macro.h"
 
+/* This is the same as glibc's internal __compar_d_fn_t type. glibc exports a public comparison_fn_t, for the
+ * external type __compar_fn_t, but doesn't do anything similar for __compar_d_fn_t. Let's hence do that
+ * ourselves, picking a name that is obvious, but likely enough to not clash with glibc's choice of naming if
+ * they should ever add one. */
+typedef int (*comparison_userdata_fn_t)(const void *, const void *, void *);
+
 void *xbsearch_r(const void *key, const void *base, size_t nmemb, size_t size,
-                 __compar_d_fn_t compar, void *arg);
+                 comparison_userdata_fn_t compar, void *arg);
 
 #define typesafe_bsearch_r(k, b, n, func, userdata)                     \
         ({                                                              \
                 const typeof(b[0]) *_k = k;                             \
                 int (*_func_)(const typeof(b[0])*, const typeof(b[0])*, typeof(userdata)) = func; \
-                xbsearch_r((const void*) _k, (b), (n), sizeof((b)[0]), (__compar_d_fn_t) _func_, userdata); \
+                xbsearch_r((const void*) _k, (b), (n), sizeof((b)[0]), (comparison_userdata_fn_t) _func_, userdata); \
         })
 
 /**
@@ -20,7 +26,7 @@ void *xbsearch_r(const void *key, const void *base, size_t nmemb, size_t size,
  * that only if nmemb > 0.
  */
 static inline void* bsearch_safe(const void *key, const void *base,
-                                 size_t nmemb, size_t size, __compar_fn_t compar) {
+                                 size_t nmemb, size_t size, comparison_fn_t compar) {
         if (nmemb <= 0)
                 return NULL;
 
@@ -32,14 +38,14 @@ static inline void* bsearch_safe(const void *key, const void *base,
         ({                                                              \
                 const typeof(b[0]) *_k = k;                             \
                 int (*_func_)(const typeof(b[0])*, const typeof(b[0])*) = func; \
-                bsearch_safe((const void*) _k, (b), (n), sizeof((b)[0]), (__compar_fn_t) _func_); \
+                bsearch_safe((const void*) _k, (b), (n), sizeof((b)[0]), (comparison_fn_t) _func_); \
         })
 
 /**
  * Normal qsort requires base to be nonnull. Here were require
  * that only if nmemb > 0.
  */
-static inline void _qsort_safe(void *base, size_t nmemb, size_t size, __compar_fn_t compar) {
+static inline void _qsort_safe(void *base, size_t nmemb, size_t size, comparison_fn_t compar) {
         if (nmemb <= 1)
                 return;
 
@@ -52,10 +58,10 @@ static inline void _qsort_safe(void *base, size_t nmemb, size_t size, __compar_f
 #define typesafe_qsort(p, n, func)                                      \
         ({                                                              \
                 int (*_func_)(const typeof(p[0])*, const typeof(p[0])*) = func; \
-                _qsort_safe((p), (n), sizeof((p)[0]), (__compar_fn_t) _func_); \
+                _qsort_safe((p), (n), sizeof((p)[0]), (comparison_fn_t) _func_); \
         })
 
-static inline void qsort_r_safe(void *base, size_t nmemb, size_t size, __compar_d_fn_t compar, void *userdata) {
+static inline void qsort_r_safe(void *base, size_t nmemb, size_t size, comparison_userdata_fn_t compar, void *userdata) {
         if (nmemb <= 1)
                 return;
 
@@ -66,7 +72,7 @@ static inline void qsort_r_safe(void *base, size_t nmemb, size_t size, __compar_
 #define typesafe_qsort_r(p, n, func, userdata)                          \
         ({                                                              \
                 int (*_func_)(const typeof(p[0])*, const typeof(p[0])*, typeof(userdata)) = func; \
-                qsort_r_safe((p), (n), sizeof((p)[0]), (__compar_d_fn_t) _func_, userdata); \
+                qsort_r_safe((p), (n), sizeof((p)[0]), (comparison_userdata_fn_t) _func_, userdata); \
         })
 
 int cmp_int(const int *a, const int *b);
index 9583dda9e5574fb076c25513dd99ed3d0d65157d..c795d3da8f2ff26188e4258322a3805d23f232e3 100644 (file)
@@ -55,9 +55,9 @@ typedef uint64_t __sd_bitwise be64_t;
 #undef le64toh
 
 #if __BYTE_ORDER == __LITTLE_ENDIAN
-#define bswap_16_on_le(x) __bswap_16(x)
-#define bswap_32_on_le(x) __bswap_32(x)
-#define bswap_64_on_le(x) __bswap_64(x)
+#define bswap_16_on_le(x) bswap_16(x)
+#define bswap_32_on_le(x) bswap_32(x)
+#define bswap_64_on_le(x) bswap_64(x)
 #define bswap_16_on_be(x) (x)
 #define bswap_32_on_be(x) (x)
 #define bswap_64_on_be(x) (x)
@@ -65,9 +65,9 @@ typedef uint64_t __sd_bitwise be64_t;
 #define bswap_16_on_le(x) (x)
 #define bswap_32_on_le(x) (x)
 #define bswap_64_on_le(x) (x)
-#define bswap_16_on_be(x) __bswap_16(x)
-#define bswap_32_on_be(x) __bswap_32(x)
-#define bswap_64_on_be(x) __bswap_64(x)
+#define bswap_16_on_be(x) bswap_16(x)
+#define bswap_32_on_be(x) bswap_32(x)
+#define bswap_64_on_be(x) bswap_64(x)
 #endif
 
 static inline le16_t htole16(uint16_t value) { return (le16_t __sd_force) bswap_16_on_be(value); }
index f4022f7c86984a1f59fb3a074e8451b4a334c362..b659d6905d9c616dc3b8d10cd3c02d6033ed8573 100644 (file)
@@ -671,7 +671,7 @@ static int parse_timestamp_impl(const char *t, usec_t *usec, bool with_tz) {
                         goto finish;
 
                 } else if ((k = endswith(t, " ago"))) {
-                        t = strndupa(t, k - t);
+                        t = strndupa_safe(t, k - t);
 
                         r = parse_sec(t, &minus);
                         if (r < 0)
@@ -680,7 +680,7 @@ static int parse_timestamp_impl(const char *t, usec_t *usec, bool with_tz) {
                         goto finish;
 
                 } else if ((k = endswith(t, " left"))) {
-                        t = strndupa(t, k - t);
+                        t = strndupa_safe(t, k - t);
 
                         r = parse_sec(t, &plus);
                         if (r < 0)
@@ -692,7 +692,7 @@ static int parse_timestamp_impl(const char *t, usec_t *usec, bool with_tz) {
                 /* See if the timestamp is suffixed with UTC */
                 utc = endswith_no_case(t, " UTC");
                 if (utc)
-                        t = strndupa(t, utc - t);
+                        t = strndupa_safe(t, utc - t);
                 else {
                         const char *e = NULL;
                         int j;
@@ -723,7 +723,7 @@ static int parse_timestamp_impl(const char *t, usec_t *usec, bool with_tz) {
 
                         if (IN_SET(j, 0, 1)) {
                                 /* Found one of the two timezones specified. */
-                                t = strndupa(t, e - t - 1);
+                                t = strndupa_safe(t, e - t - 1);
                                 dst = j;
                                 tzn = tzname[j];
                         }
@@ -924,7 +924,7 @@ int parse_timestamp(const char *t, usec_t *usec) {
 
                 /* Cut off the timezone if we don't need it. */
                 if (with_tz)
-                        t = strndupa(t, last_space - t);
+                        t = strndupa_safe(t, last_space - t);
 
                 shared->return_value = parse_timestamp_impl(t, &shared->usec, with_tz);
 
index 385ec514b4171832aa948be95a2f658febc7fffb..aee2d9dc595a24a7936b07db5cb5538a11cdf80b 100644 (file)
@@ -1085,3 +1085,14 @@ int is_this_me(const char *username) {
 
         return uid == getuid();
 }
+
+const char *get_home_root(void) {
+        const char *e;
+
+        /* For debug purposes allow overriding where we look for home dirs */
+        e = secure_getenv("SYSTEMD_HOME_ROOT");
+        if (e && path_is_absolute(e) && path_is_normalized(e))
+                return e;
+
+        return "/home";
+}
index fd00b47b7665c55ced366dd2e57d259bdc6302e2..ab1ce48b2df8e8b0d2cbe700fae9549b19bdf97f 100644 (file)
@@ -112,6 +112,8 @@ bool is_nologin_shell(const char *shell);
 
 int is_this_me(const char *username);
 
+const char *get_home_root(void);
+
 /* A locked *and* invalid password for "struct spwd"'s .sp_pwdp and "struct passwd"'s .pw_passwd field */
 #define PASSWORD_LOCKED_AND_INVALID "!*"
 
index 955b18bd2aaf5bf8b98f042d53fcc22b1354f1e3..43e74b773fc3f895fb36f26e1fc38131d23cdecd 100644 (file)
@@ -119,62 +119,57 @@ int on_ac_power(void) {
         bool found_offline = false, found_online = false;
         _cleanup_closedir_ DIR *d = NULL;
         struct dirent *de;
+        int r;
 
         d = opendir("/sys/class/power_supply");
         if (!d)
                 return errno == ENOENT ? true : -errno;
 
         FOREACH_DIRENT(de, d, return -errno) {
-                _cleanup_close_ int fd = -1, device = -1;
-                char contents[6];
-                ssize_t n;
+                _cleanup_close_ int device_fd = -1;
+                _cleanup_free_ char *contents = NULL;
+                unsigned v;
 
-                device = openat(dirfd(d), de->d_name, O_DIRECTORY|O_RDONLY|O_CLOEXEC|O_NOCTTY);
-                if (device < 0) {
+                device_fd = openat(dirfd(d), de->d_name, O_DIRECTORY|O_RDONLY|O_CLOEXEC);
+                if (device_fd < 0) {
                         if (IN_SET(errno, ENOENT, ENOTDIR))
                                 continue;
 
                         return -errno;
                 }
 
-                fd = openat(device, "type", O_RDONLY|O_CLOEXEC|O_NOCTTY);
-                if (fd < 0) {
-                        if (errno == ENOENT)
-                                continue;
-
-                        return -errno;
-                }
+                r = read_virtual_file_at(device_fd, "type", SIZE_MAX, &contents, NULL);
+                if (r == -ENOENT)
+                        continue;
+                if (r < 0)
+                        return r;
 
-                n = read(fd, contents, sizeof(contents));
-                if (n < 0)
-                        return -errno;
+                delete_trailing_chars(contents, NEWLINE);
 
-                if (n != 6 || memcmp(contents, "Mains\n", 6))
+                /* We assume every power source is AC, except for batteries. See
+                 * https://github.com/torvalds/linux/blob/4eef766b7d4d88f0b984781bc1bcb574a6eafdc7/include/linux/power_supply.h#L176
+                 * for defined power source types. Also see:
+                 * https://www.kernel.org/doc/Documentation/ABI/testing/sysfs-class-power */
+                if (streq(contents, "Battery"))
                         continue;
 
-                safe_close(fd);
-                fd = openat(device, "online", O_RDONLY|O_CLOEXEC|O_NOCTTY);
-                if (fd < 0) {
-                        if (errno == ENOENT)
-                                continue;
-
-                        return -errno;
-                }
+                contents = mfree(contents);
 
-                n = read(fd, contents, sizeof(contents));
-                if (n < 0)
-                        return -errno;
+                r = read_virtual_file_at(device_fd, "online", SIZE_MAX, &contents, NULL);
+                if (r == -ENOENT)
+                        continue;
+                if (r < 0)
+                        return r;
 
-                if (n != 2 || contents[1] != '\n')
-                        return -EIO;
+                delete_trailing_chars(contents, NEWLINE);
 
-                if (contents[0] == '1') {
+                r = safe_atou(contents, &v);
+                if (r < 0)
+                        return r;
+                if (v > 0) /* At least 1 and 2 are defined as different types of 'online' */
                         found_online = true;
-                        break;
-                } else if (contents[0] == '0')
-                        found_offline = true;
                 else
-                        return -EIO;
+                        found_offline = true;
         }
 
         return found_online || !found_offline;
index c9c4416ef78c8759eb85a8cb120ac9a8a6737b5e..64581ad2e10d1c7cc6eba099979cd8ceef66fbd5 100644 (file)
@@ -165,6 +165,7 @@ static int detect_vm_dmi_vendor(void) {
                 { "Parallels",           VIRTUALIZATION_PARALLELS },
                 /* https://wiki.freebsd.org/bhyve */
                 { "BHYVE",               VIRTUALIZATION_BHYVE     },
+                { "Microsoft",           VIRTUALIZATION_MICROSOFT },
         };
         int r;
 
@@ -276,19 +277,6 @@ static int detect_vm_dmi(void) {
 #endif
 }
 
-static int detect_vm_xen(void) {
-
-        /* Check for Dom0 will be executed later in detect_vm_xen_dom0
-           The presence of /proc/xen indicates some form of a Xen domain */
-        if (access("/proc/xen", F_OK) < 0) {
-                log_debug("Virtualization XEN not found, /proc/xen does not exist");
-                return VIRTUALIZATION_NONE;
-        }
-
-        log_debug("Virtualization XEN found (/proc/xen exists)");
-        return VIRTUALIZATION_XEN;
-}
-
 #define XENFEAT_dom0 11 /* xen/include/public/features.h */
 #define PATH_FEATURES "/sys/hypervisor/properties/features"
 /* Returns -errno, or 0 for domU, or 1 for dom0 */
@@ -342,6 +330,26 @@ static int detect_vm_xen_dom0(void) {
         }
 }
 
+static int detect_vm_xen(void) {
+        int r;
+
+        /* The presence of /proc/xen indicates some form of a Xen domain */
+        if (access("/proc/xen", F_OK) < 0) {
+                log_debug("Virtualization XEN not found, /proc/xen does not exist");
+                return VIRTUALIZATION_NONE;
+        }
+        log_debug("Virtualization XEN found (/proc/xen exists)");
+
+        /* Ignore the Xen hypervisor if we are in Dom0 */
+        r = detect_vm_xen_dom0();
+        if (r < 0)
+                return r;
+        if (r > 0)
+                return VIRTUALIZATION_NONE;
+
+        return VIRTUALIZATION_XEN;
+}
+
 static int detect_vm_hypervisor(void) {
         _cleanup_free_ char *hvtype = NULL;
         int r;
@@ -435,7 +443,8 @@ int detect_vm(void) {
          *
          * â†’ First, try to detect Oracle Virtualbox and Amazon EC2 Nitro, even if they use KVM, as well as Xen even if
          *   it cloaks as Microsoft Hyper-V. Attempt to detect uml at this stage also since it runs as a user-process
-         *   nested inside other VMs.
+         *   nested inside other VMs. Also check for Xen now, because Xen PV mode does not override CPUID when nested
+         *   inside another hypervisor.
          *
          * â†’ Second, try to detect from CPUID, this will report KVM for whatever software is used even if info in DMI is
          *   overwritten.
@@ -457,6 +466,15 @@ int detect_vm(void) {
         else if (r != VIRTUALIZATION_NONE)
                 goto finish;
 
+        /* Detect Xen */
+        r = detect_vm_xen();
+        if (r < 0)
+                return r;
+        if (r == VIRTUALIZATION_VM_OTHER)
+                other = true;
+        else if (r != VIRTUALIZATION_NONE)
+                goto finish;
+
         /* Detect from CPUID */
         r = detect_vm_cpuid();
         if (r < 0)
@@ -476,20 +494,7 @@ int detect_vm(void) {
                 goto finish;
         }
 
-        /* x86 xen will most likely be detected by cpuid. If not (most likely
-         * because we're not an x86 guest), then we should try the /proc/xen
-         * directory next. If that's not found, then we check for the high-level
-         * hypervisor sysfs file.
-         */
-
-        r = detect_vm_xen();
-        if (r < 0)
-                return r;
-        if (r == VIRTUALIZATION_VM_OTHER)
-                other = true;
-        else if (r != VIRTUALIZATION_NONE)
-                goto finish;
-
+        /* Check high-level hypervisor sysfs file */
         r = detect_vm_hypervisor();
         if (r < 0)
                 return r;
@@ -511,18 +516,7 @@ int detect_vm(void) {
                 return r;
 
 finish:
-        /* x86 xen Dom0 is detected as XEN in hypervisor and maybe others.
-         * In order to detect the Dom0 as not virtualization we need to
-         * double-check it */
-        if (r == VIRTUALIZATION_XEN) {
-                int dom0;
-
-                dom0 = detect_vm_xen_dom0();
-                if (dom0 < 0)
-                        return dom0;
-                if (dom0 > 0)
-                        r = VIRTUALIZATION_NONE;
-        } else if (r == VIRTUALIZATION_NONE && other)
+        if (r == VIRTUALIZATION_NONE && other)
                 r = VIRTUALIZATION_VM_OTHER;
 
         cached_found = r;
index cb0688672783fafd658d3174cfae8abf6d9bf61d..9e4b0d1f72166128804a2826f134f9ee411886da 100644 (file)
@@ -162,7 +162,7 @@ static int parse_counter(
                                        "Can't parse empty 'tries left' counter from LoaderBootCountPath: %s",
                                        path);
 
-        z = strndupa(e, k);
+        z = strndupa_safe(e, k);
         r = safe_atou64(z, &left);
         if (r < 0)
                 return log_error_errno(r, "Failed to parse 'tries left' counter from LoaderBootCountPath: %s", path);
@@ -178,7 +178,7 @@ static int parse_counter(
                                                "Can't parse empty 'tries done' counter from LoaderBootCountPath: %s",
                                                path);
 
-                z = strndupa(e, k);
+                z = strndupa_safe(e, k);
                 r = safe_atou64(z, &done);
                 if (r < 0)
                         return log_error_errno(r, "Failed to parse 'tries done' counter from LoaderBootCountPath: %s", path);
index 60060cd60c0066401391f54d1dd5297eaa9705d2..b0b3d4f8ae049abc745ff000d95d44251f061e16 100644 (file)
@@ -1099,6 +1099,9 @@ static int help(int argc, char *argv[], void *userdata) {
                "  list                List boot loader entries\n"
                "  set-default ID      Set default boot loader entry\n"
                "  set-oneshot ID      Set default boot loader entry, for next boot only\n"
+               "  set-timeout SECONDS Set the menu timeout\n"
+               "  set-timeout-oneshot SECONDS\n"
+               "                      Set the menu timeout for the next boot only\n"
                "\n%3$ssystemd-boot Commands:%4$s\n"
                "  install             Install systemd-boot to the ESP and EFI variables\n"
                "  update              Update systemd-boot in the ESP and EFI variables\n"
@@ -1773,6 +1776,37 @@ static int verb_is_installed(int argc, char *argv[], void *userdata) {
         return EXIT_SUCCESS;
 }
 
+static int parse_timeout(const char *arg1, char16_t **ret_timeout, size_t *ret_timeout_size) {
+        char utf8[DECIMAL_STR_MAX(usec_t)];
+        char16_t *encoded;
+        usec_t timeout;
+        int r;
+
+        assert(arg1);
+        assert(ret_timeout);
+        assert(ret_timeout_size);
+
+        if (streq(arg1, "menu-force"))
+                timeout = USEC_INFINITY;
+        else if (streq(arg1, "menu-hidden"))
+                timeout = 0;
+        else {
+                r = parse_time(arg1, &timeout, USEC_PER_SEC);
+                if (r < 0)
+                        return log_error_errno(r, "Failed to parse timeout '%s': %m", arg1);
+                if (timeout != USEC_INFINITY && timeout > UINT32_MAX * USEC_PER_SEC)
+                        log_warning("Timeout is too long and will be treated as 'menu-force' instead.");
+        }
+
+        xsprintf(utf8, USEC_FMT, MIN(timeout / USEC_PER_SEC, UINT32_MAX));
+        encoded = utf8_to_utf16(utf8, strlen(utf8));
+        if (!encoded)
+                return log_oom();
+        *ret_timeout = encoded;
+        *ret_timeout_size = char16_strlen(encoded) * 2 + 2;
+        return 0;
+}
+
 static int parse_loader_entry_target_arg(const char *arg1, char16_t **ret_target, size_t *ret_target_size) {
         int r;
         if (streq(arg1, "@current")) {
@@ -1798,7 +1832,7 @@ static int parse_loader_entry_target_arg(const char *arg1, char16_t **ret_target
         return 0;
 }
 
-static int verb_set_default(int argc, char *argv[], void *userdata) {
+static int verb_set_efivar(int argc, char *argv[], void *userdata) {
         int r;
 
         if (!is_efi_boot())
@@ -1821,24 +1855,39 @@ static int verb_set_default(int argc, char *argv[], void *userdata) {
 
         if (!arg_touch_variables)
                 return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
-                                       "'%s' operation cannot be combined with --touch-variables=no.",
+                                       "'%s' operation cannot be combined with --no-variables.",
                                        argv[0]);
 
-        const char *variable = streq(argv[0], "set-default") ?
-                EFI_LOADER_VARIABLE(LoaderEntryDefault) : EFI_LOADER_VARIABLE(LoaderEntryOneShot);
+        const char *variable;
+        int (* arg_parser)(const char *, char16_t **, size_t *);
+
+        if (streq(argv[0], "set-default")) {
+                variable = EFI_LOADER_VARIABLE(LoaderEntryDefault);
+                arg_parser = parse_loader_entry_target_arg;
+        } else if (streq(argv[0], "set-oneshot")) {
+                variable = EFI_LOADER_VARIABLE(LoaderEntryOneShot);
+                arg_parser = parse_loader_entry_target_arg;
+        } else if (streq(argv[0], "set-timeout")) {
+                variable = EFI_LOADER_VARIABLE(LoaderConfigTimeout);
+                arg_parser = parse_timeout;
+        } else if (streq(argv[0], "set-timeout-oneshot")) {
+                variable = EFI_LOADER_VARIABLE(LoaderConfigTimeoutOneShot);
+                arg_parser = parse_timeout;
+        } else
+                assert_not_reached();
 
         if (isempty(argv[1])) {
                 r = efi_set_variable(variable, NULL, 0);
                 if (r < 0 && r != -ENOENT)
                         return log_error_errno(r, "Failed to remove EFI variable '%s': %m", variable);
         } else {
-                _cleanup_free_ char16_t *target = NULL;
-                size_t target_size = 0;
+                _cleanup_free_ char16_t *value = NULL;
+                size_t value_size = 0;
 
-                r = parse_loader_entry_target_arg(argv[1], &target, &target_size);
+                r = arg_parser(argv[1], &value, &value_size);
                 if (r < 0)
                         return r;
-                r = efi_set_variable(variable, target, target_size);
+                r = efi_set_variable(variable, value, value_size);
                 if (r < 0)
                         return log_error_errno(r, "Failed to update EFI variable '%s': %m", variable);
         }
@@ -1943,8 +1992,10 @@ static int bootctl_main(int argc, char *argv[]) {
                 { "remove",              VERB_ANY, 1,        0,            verb_remove              },
                 { "is-installed",        VERB_ANY, 1,        0,            verb_is_installed        },
                 { "list",                VERB_ANY, 1,        0,            verb_list                },
-                { "set-default",         2,        2,        0,            verb_set_default         },
-                { "set-oneshot",         2,        2,        0,            verb_set_default         },
+                { "set-default",         2,        2,        0,            verb_set_efivar          },
+                { "set-oneshot",         2,        2,        0,            verb_set_efivar          },
+                { "set-timeout",         2,        2,        0,            verb_set_efivar          },
+                { "set-timeout-oneshot", 2,        2,        0,            verb_set_efivar          },
                 { "random-seed",         VERB_ANY, 1,        0,            verb_random_seed         },
                 { "systemd-efi-options", VERB_ANY, 2,        0,            verb_systemd_efi_options },
                 { "reboot-to-firmware",  VERB_ANY, 2,        0,            verb_reboot_to_firmware  },
index d82d679a47d798d732b9b43093a627585089918b..5fdf26240ad91dbf544c0370eefbc5a361b08f24 100644 (file)
@@ -17,6 +17,7 @@
 #include "secure-boot.h"
 #include "shim.h"
 #include "util.h"
+#include "xbootldr.h"
 
 #ifndef EFI_OS_INDICATIONS_BOOT_TO_FW_UI
 #define EFI_OS_INDICATIONS_BOOT_TO_FW_UI 0x0000000000000001ULL
@@ -25,7 +26,7 @@
 #define TEXT_ATTR_SWAP(c) EFI_TEXT_ATTR(((c) & 0b11110000) >> 4, (c) & 0b1111)
 
 /* magic string to find in the binary image */
-static const char _used_ _section_(".sdmagic") magic[] = "#### LoaderInfo: systemd-boot " GIT_VERSION " ####";
+_used_ _section_(".sdmagic") static const char magic[] = "#### LoaderInfo: systemd-boot " GIT_VERSION " ####";
 
 enum loader_type {
         LOADER_UNDEFINED,
@@ -60,9 +61,9 @@ typedef struct {
         UINTN entry_count;
         INTN idx_default;
         INTN idx_default_efivar;
-        UINTN timeout_sec;
-        UINTN timeout_sec_config;
-        INTN timeout_sec_efivar;
+        UINT32 timeout_sec; /* Actual timeout used (efi_main() override > efivar > config). */
+        UINT32 timeout_sec_config;
+        UINT32 timeout_sec_efivar;
         CHAR16 *entry_default_pattern;
         CHAR16 *entry_oneshot;
         CHAR16 *options_edit;
@@ -75,6 +76,18 @@ typedef struct {
         RandomSeedMode random_seed_mode;
 } Config;
 
+/* These values have been chosen so that the transitions the user sees could
+ * employ unsigned over-/underflow like this:
+ * efivar unset â†” force menu â†” no timeout/skip menu â†” 1 s â†” 2 s â†” â€¦ */
+enum {
+        TIMEOUT_MIN         = 1,
+        TIMEOUT_MAX         = UINT32_MAX - 2U,
+        TIMEOUT_UNSET       = UINT32_MAX - 1U,
+        TIMEOUT_MENU_FORCE  = UINT32_MAX,
+        TIMEOUT_MENU_HIDDEN = 0,
+        TIMEOUT_TYPE_MAX    = UINT32_MAX,
+};
+
 static VOID cursor_left(UINTN *cursor, UINTN *first) {
         assert(cursor);
         assert(first);
@@ -366,6 +379,38 @@ static UINTN entry_lookup_key(Config *config, UINTN start, CHAR16 key) {
         return -1;
 }
 
+static CHAR16 *update_timeout_efivar(UINT32 *t, BOOLEAN inc) {
+        assert(t);
+
+        switch (*t) {
+        case TIMEOUT_MAX:
+                *t = inc ? TIMEOUT_MAX : (*t - 1);
+                break;
+        case TIMEOUT_UNSET:
+                *t = inc ? TIMEOUT_MENU_FORCE : TIMEOUT_UNSET;
+                break;
+        case TIMEOUT_MENU_FORCE:
+                *t = inc ? TIMEOUT_MENU_HIDDEN : TIMEOUT_UNSET;
+                break;
+        case TIMEOUT_MENU_HIDDEN:
+                *t = inc ? TIMEOUT_MIN : TIMEOUT_MENU_FORCE;
+                break;
+        default:
+                *t += inc ? 1 : -1;
+        }
+
+        switch (*t) {
+        case TIMEOUT_UNSET:
+                return StrDuplicate(L"Menu timeout defined by configuration file.");
+        case TIMEOUT_MENU_FORCE:
+                return StrDuplicate(L"Timeout disabled, menu will always be shown.");
+        case TIMEOUT_MENU_HIDDEN:
+                return StrDuplicate(L"Menu disabled. Hold down key at bootup to show menu.");
+        default:
+                return PoolPrint(L"Menu timeout set to %u s.", *t);
+        }
+}
+
 static VOID print_status(Config *config, CHAR16 *loaded_image_path) {
         UINT64 key;
         UINTN timeout;
@@ -400,10 +445,11 @@ static VOID print_status(Config *config, CHAR16 *loaded_image_path) {
         Print(L"\n--- press key ---\n\n");
         console_key_read(&key, 0);
 
-        Print(L"timeout:                %u\n", config->timeout_sec);
-        if (config->timeout_sec_efivar >= 0)
-                Print(L"timeout (EFI var):      %d\n", config->timeout_sec_efivar);
-        Print(L"timeout (config):       %u\n", config->timeout_sec_config);
+        Print(L"timeout:                %u s\n", config->timeout_sec);
+        if (config->timeout_sec_efivar != TIMEOUT_UNSET)
+                Print(L"timeout (EFI var):      %u s\n", config->timeout_sec_efivar);
+        if (config->timeout_sec_config != TIMEOUT_UNSET)
+                Print(L"timeout (config):       %u s\n", config->timeout_sec_config);
         if (config->entry_default_pattern)
                 Print(L"default pattern:        '%s'\n", config->entry_default_pattern);
         Print(L"editor:                 %s\n", yes_no(config->editor));
@@ -517,9 +563,10 @@ static BOOLEAN menu_run(
         BOOLEAN refresh = TRUE, highlight = FALSE;
         UINTN x_start = 0, y_start = 0, y_status = 0;
         UINTN x_max, y_max;
-        CHAR16 **lines = NULL;
+        _cleanup_(strv_freep) CHAR16 **lines = NULL;
         _cleanup_freepool_ CHAR16 *clearline = NULL, *status = NULL;
-        UINTN timeout_remain = config->timeout_sec;
+        UINT32 timeout_efivar_saved = config->timeout_sec_efivar;
+        UINT32 timeout_remain = config->timeout_sec == TIMEOUT_MENU_FORCE ? 0 : config->timeout_sec;
         INT16 idx;
         BOOLEAN exit = FALSE, run = TRUE;
         INT64 console_mode_initial = ST->ConOut->Mode->Mode, console_mode_efivar_saved = config->console_mode_efivar;
@@ -576,15 +623,11 @@ static BOOLEAN menu_run(
                         /* Put status line after the entry list, but give it some breathing room. */
                         y_status = MIN(y_start + MIN(visible_max, config->entry_count) + 4, y_max - 1);
 
-                        if (lines) {
-                                for (UINTN i = 0; i < config->entry_count; i++)
-                                        FreePool(lines[i]);
-                                FreePool(lines);
-                                FreePool(clearline);
-                        }
+                        strv_free(lines);
+                        FreePool(clearline);
 
                         /* menu entries title lines */
-                        lines = AllocatePool(sizeof(CHAR16 *) * config->entry_count);
+                        lines = AllocatePool((config->entry_count + 1) * sizeof(CHAR16 *));
                         for (UINTN i = 0; i < config->entry_count; i++) {
                                 UINTN j, padding;
 
@@ -601,6 +644,7 @@ static BOOLEAN menu_run(
                                         lines[i][j] = ' ';
                                 lines[i][line_width] = '\0';
                         }
+                        lines[config->entry_count] = NULL;
 
                         clearline = AllocatePool((x_max+1) * sizeof(CHAR16));
                         for (UINTN i = 0; i < x_max; i++)
@@ -640,7 +684,7 @@ static BOOLEAN menu_run(
 
                 if (timeout_remain > 0) {
                         FreePool(status);
-                        status = PoolPrint(L"Boot in %d s.", timeout_remain);
+                        status = PoolPrint(L"Boot in %u s.", timeout_remain);
                 }
 
                 /* print status at last line of screen */
@@ -768,44 +812,12 @@ static BOOLEAN menu_run(
 
                 case KEYPRESS(0, 0, '-'):
                 case KEYPRESS(0, 0, 'T'):
-                        if (config->timeout_sec_efivar > 0) {
-                                config->timeout_sec_efivar--;
-                                efivar_set_uint_string(
-                                        LOADER_GUID,
-                                        L"LoaderConfigTimeout",
-                                        config->timeout_sec_efivar,
-                                        EFI_VARIABLE_NON_VOLATILE);
-                                if (config->timeout_sec_efivar > 0)
-                                        status = PoolPrint(L"Menu timeout set to %d s.", config->timeout_sec_efivar);
-                                else
-                                        status = StrDuplicate(L"Menu disabled. Hold down key at bootup to show menu.");
-                        } else if (config->timeout_sec_efivar <= 0){
-                                config->timeout_sec_efivar = -1;
-                                efivar_set(
-                                        LOADER_GUID, L"LoaderConfigTimeout", NULL, EFI_VARIABLE_NON_VOLATILE);
-                                if (config->timeout_sec_config > 0)
-                                        status = PoolPrint(L"Menu timeout of %d s is defined by configuration file.",
-                                                           config->timeout_sec_config);
-                                else
-                                        status = StrDuplicate(L"Menu disabled. Hold down key at bootup to show menu.");
-                        }
+                        status = update_timeout_efivar(&config->timeout_sec_efivar, FALSE);
                         break;
 
                 case KEYPRESS(0, 0, '+'):
                 case KEYPRESS(0, 0, 't'):
-                        if (config->timeout_sec_efivar == -1 && config->timeout_sec_config == 0)
-                                config->timeout_sec_efivar++;
-                        config->timeout_sec_efivar++;
-                        efivar_set_uint_string(
-                                LOADER_GUID,
-                                L"LoaderConfigTimeout",
-                                config->timeout_sec_efivar,
-                                EFI_VARIABLE_NON_VOLATILE);
-                        if (config->timeout_sec_efivar > 0)
-                                status = PoolPrint(L"Menu timeout set to %d s.",
-                                                   config->timeout_sec_efivar);
-                        else
-                                status = StrDuplicate(L"Menu disabled. Hold down key at bootup to show menu.");
+                        status = update_timeout_efivar(&config->timeout_sec_efivar, TRUE);
                         break;
 
                 case KEYPRESS(0, 0, 'e'):
@@ -888,9 +900,8 @@ static BOOLEAN menu_run(
 
         *chosen_entry = config->entries[idx_highlight];
 
-        /* The user is likely to cycle through several modes before
-         * deciding to keep one. Therefore, we update the EFI var after
-         * we left the menu to reduce nvram writes. */
+        /* Update EFI vars after we left the menu to reduce NVRAM writes. */
+
         if (console_mode_efivar_saved != config->console_mode_efivar) {
                 if (config->console_mode_efivar == CONSOLE_MODE_KEEP)
                         efivar_set(LOADER_GUID, L"LoaderConfigConsoleMode", NULL, EFI_VARIABLE_NON_VOLATILE);
@@ -899,9 +910,13 @@ static BOOLEAN menu_run(
                                                config->console_mode_efivar, EFI_VARIABLE_NON_VOLATILE);
         }
 
-        for (UINTN i = 0; i < config->entry_count; i++)
-                FreePool(lines[i]);
-        FreePool(lines);
+        if (timeout_efivar_saved != config->timeout_sec_efivar) {
+                if (config->timeout_sec_efivar == TIMEOUT_UNSET)
+                        efivar_set(LOADER_GUID, L"LoaderConfigTimeout", NULL, EFI_VARIABLE_NON_VOLATILE);
+                else
+                        efivar_set_uint_string(LOADER_GUID, L"LoaderConfigTimeout",
+                                               config->timeout_sec_efivar, EFI_VARIABLE_NON_VOLATILE);
+        }
 
         clear_screen(COLOR_NORMAL);
         return run;
@@ -939,6 +954,10 @@ static VOID config_entry_free(ConfigEntry *entry) {
         FreePool(entry);
 }
 
+static inline VOID config_entry_freep(ConfigEntry **entry) {
+        config_entry_free(*entry);
+}
+
 static CHAR8 *line_get_key_value(
                 CHAR8 *content,
                 const CHAR8 *sep,
@@ -1023,10 +1042,16 @@ static VOID config_defaults_load_from_file(Config *config, CHAR8 *content) {
 
         while ((line = line_get_key_value(content, (CHAR8 *)" \t", &pos, &key, &value))) {
                 if (strcmpa((CHAR8 *)"timeout", key) == 0) {
-                        _cleanup_freepool_ CHAR16 *s = NULL;
+                        if (strcmpa((CHAR8*) "menu-force", value) == 0)
+                                config->timeout_sec_config = TIMEOUT_MENU_FORCE;
+                        else if (strcmpa((CHAR8*) "menu-hidden", value) == 0)
+                                config->timeout_sec_config = TIMEOUT_MENU_HIDDEN;
+                        else {
+                                _cleanup_freepool_ CHAR16 *s = NULL;
 
-                        s = stra_to_str(value);
-                        config->timeout_sec_config = Atoi(s);
+                                s = stra_to_str(value);
+                                config->timeout_sec_config = MIN(Atoi(s), TIMEOUT_TYPE_MAX);
+                        }
                         config->timeout_sec = config->timeout_sec_config;
                         continue;
                 }
@@ -1279,7 +1304,7 @@ static VOID config_entry_add_from_file(
                 CHAR8 *content,
                 const CHAR16 *loaded_image_path) {
 
-        ConfigEntry *entry;
+        _cleanup_(config_entry_freep) ConfigEntry *entry = NULL;
         CHAR8 *line;
         UINTN pos = 0;
         CHAR8 *key, *value;
@@ -1293,7 +1318,6 @@ static VOID config_entry_add_from_file(
         assert(path);
         assert(file);
         assert(content);
-        assert(loaded_image_path);
 
         entry = AllocatePool(sizeof(ConfigEntry));
 
@@ -1390,17 +1414,13 @@ static VOID config_entry_add_from_file(
                 }
         }
 
-        if (entry->type == LOADER_UNDEFINED) {
-                config_entry_free(entry);
+        if (entry->type == LOADER_UNDEFINED)
                 return;
-        }
 
         /* check existence */
         err = uefi_call_wrapper(root_dir->Open, 5, root_dir, &handle, entry->loader, EFI_FILE_MODE_READ, 0ULL);
-        if (EFI_ERROR(err)) {
-                config_entry_free(entry);
+        if (EFI_ERROR(err))
                 return;
-        }
         uefi_call_wrapper(handle->Close, 1, handle);
 
         /* add initrd= to options */
@@ -1422,6 +1442,7 @@ static VOID config_entry_add_from_file(
         config_add_entry(config, entry);
 
         config_entry_parse_tries(entry, path, file, L".conf");
+        TAKE_PTR(entry);
 }
 
 static VOID config_load_defaults(Config *config, EFI_FILE *root_dir) {
@@ -1439,6 +1460,8 @@ static VOID config_load_defaults(Config *config, EFI_FILE *root_dir) {
                 .idx_default_efivar = -1,
                 .console_mode = CONSOLE_MODE_KEEP,
                 .console_mode_efivar = CONSOLE_MODE_KEEP,
+                .timeout_sec_config = TIMEOUT_UNSET,
+                .timeout_sec_efivar = TIMEOUT_UNSET,
         };
 
         err = file_read(root_dir, L"\\loader\\loader.conf", 0, 0, &content, NULL);
@@ -1447,17 +1470,16 @@ static VOID config_load_defaults(Config *config, EFI_FILE *root_dir) {
 
         err = efivar_get_uint_string(LOADER_GUID, L"LoaderConfigTimeout", &value);
         if (!EFI_ERROR(err)) {
-                config->timeout_sec_efivar = value > INTN_MAX ? INTN_MAX : value;
-                config->timeout_sec = value;
-        } else
-                config->timeout_sec_efivar = -1;
+                config->timeout_sec_efivar = MIN(value, TIMEOUT_TYPE_MAX);
+                config->timeout_sec = config->timeout_sec_efivar;
+        }
 
         err = efivar_get_uint_string(LOADER_GUID, L"LoaderConfigTimeoutOneShot", &value);
         if (!EFI_ERROR(err)) {
                 /* Unset variable now, after all it's "one shot". */
                 (void) efivar_set(LOADER_GUID, L"LoaderConfigTimeoutOneShot", NULL, EFI_VARIABLE_NON_VOLATILE);
 
-                config->timeout_sec = value;
+                config->timeout_sec = MIN(value, TIMEOUT_TYPE_MAX);
                 config->force_menu = TRUE; /* force the menu when this is set */
         }
 
@@ -1480,7 +1502,6 @@ static VOID config_load_entries(
         assert(config);
         assert(device);
         assert(root_dir);
-        assert(loaded_image_path);
 
         err = open_directory(root_dir, L"\\loader\\entries", &entries_dir);
         if (EFI_ERROR(err))
@@ -2070,208 +2091,19 @@ static VOID config_entry_add_linux(
         }
 }
 
-#define XBOOTLDR_GUID \
-        &(const EFI_GUID) { 0xbc13c2ff, 0x59e6, 0x4262, { 0xa3, 0x52, 0xb2, 0x75, 0xfd, 0x6f, 0x71, 0x72 } }
-
-static EFI_DEVICE_PATH *path_parent(EFI_DEVICE_PATH *path, EFI_DEVICE_PATH *node) {
-        EFI_DEVICE_PATH *parent;
-        UINTN len;
-
-        assert(path);
-        assert(node);
-
-        len = (UINT8*) NextDevicePathNode(node) - (UINT8*) path;
-        parent = (EFI_DEVICE_PATH*) AllocatePool(len + sizeof(EFI_DEVICE_PATH));
-        CopyMem(parent, path, len);
-        CopyMem((UINT8*) parent + len, EndDevicePath, sizeof(EFI_DEVICE_PATH));
-
-        return parent;
-}
-
 static VOID config_load_xbootldr(
                 Config *config,
                 EFI_HANDLE *device) {
 
-        EFI_DEVICE_PATH *partition_path, *disk_path, *copy;
-        UINT32 found_partition_number = UINT32_MAX;
-        UINT64 found_partition_start = UINT64_MAX;
-        UINT64 found_partition_size = UINT64_MAX;
-        UINT8 found_partition_signature[16] = {};
         EFI_HANDLE new_device;
         EFI_FILE *root_dir;
-        EFI_STATUS r;
+        EFI_STATUS err;
 
         assert(config);
         assert(device);
 
-        partition_path = DevicePathFromHandle(device);
-        if (!partition_path)
-                return;
-
-        for (EFI_DEVICE_PATH *node = partition_path; !IsDevicePathEnd(node); node = NextDevicePathNode(node)) {
-                EFI_HANDLE disk_handle;
-                EFI_BLOCK_IO *block_io;
-                EFI_DEVICE_PATH *p;
-
-                /* First, Let's look for the SCSI/SATA/USB/… device path node, i.e. one above the media
-                 * devices */
-                if (DevicePathType(node) != MESSAGING_DEVICE_PATH)
-                        continue;
-
-                /* Determine the device path one level up */
-                disk_path = path_parent(partition_path, node);
-                p = disk_path;
-                r = uefi_call_wrapper(BS->LocateDevicePath, 3, &BlockIoProtocol, &p, &disk_handle);
-                if (EFI_ERROR(r))
-                        continue;
-
-                r = uefi_call_wrapper(BS->HandleProtocol, 3, disk_handle, &BlockIoProtocol, (VOID **)&block_io);
-                if (EFI_ERROR(r))
-                        continue;
-
-                /* Filter out some block devices early. (We only care about block devices that aren't
-                 * partitions themselves â€” we look for GPT partition tables to parse after all â€”, and only
-                 * those which contain a medium and have at least 2 blocks.) */
-                if (block_io->Media->LogicalPartition ||
-                    !block_io->Media->MediaPresent ||
-                    block_io->Media->LastBlock <= 1)
-                        continue;
-
-                /* Try both copies of the GPT header, in case one is corrupted */
-                for (UINTN nr = 0; nr < 2; nr++) {
-                        _cleanup_freepool_ EFI_PARTITION_ENTRY* entries = NULL;
-                        union {
-                                EFI_PARTITION_TABLE_HEADER gpt_header;
-                                uint8_t space[((sizeof(EFI_PARTITION_TABLE_HEADER) + 511) / 512) * 512];
-                        } gpt_header_buffer;
-                        EFI_PARTITION_TABLE_HEADER *h = &gpt_header_buffer.gpt_header;
-                        UINT64 where;
-                        UINTN sz;
-                        UINT32 crc32, crc32_saved;
-
-                        if (nr == 0)
-                                /* Read the first copy at LBA 1 */
-                                where = 1;
-                        else
-                                /* Read the second copy at the very last LBA of this block device */
-                                where = block_io->Media->LastBlock;
-
-                        /* Read the GPT header */
-                        r = uefi_call_wrapper(block_io->ReadBlocks, 5,
-                                              block_io,
-                                              block_io->Media->MediaId,
-                                              where,
-                                              sizeof(gpt_header_buffer), &gpt_header_buffer);
-                        if (EFI_ERROR(r))
-                                continue;
-
-                        /* Some superficial validation of the GPT header */
-                        if(CompareMem(&h->Header.Signature, "EFI PART", sizeof(h->Header.Signature) != 0))
-                                continue;
-
-                        if (h->Header.HeaderSize < 92 ||
-                            h->Header.HeaderSize > 512)
-                                continue;
-
-                        if (h->Header.Revision != 0x00010000U)
-                                continue;
-
-                        /* Calculate CRC check */
-                        crc32_saved = h->Header.CRC32;
-                        h->Header.CRC32 = 0;
-                        r = BS->CalculateCrc32(&gpt_header_buffer, h->Header.HeaderSize, &crc32);
-                        h->Header.CRC32 = crc32_saved;
-                        if (EFI_ERROR(r) || crc32 != crc32_saved)
-                                continue;
-
-                        if (h->MyLBA != where)
-                                continue;
-
-                        if (h->SizeOfPartitionEntry < sizeof(EFI_PARTITION_ENTRY))
-                                continue;
-
-                        if (h->NumberOfPartitionEntries <= 0 ||
-                            h->NumberOfPartitionEntries > 1024)
-                                continue;
-
-                        if (h->SizeOfPartitionEntry > UINTN_MAX / h->NumberOfPartitionEntries) /* overflow check */
-                                continue;
-
-                        /* Now load the GPT entry table */
-                        sz = ALIGN_TO((UINTN) h->SizeOfPartitionEntry * (UINTN) h->NumberOfPartitionEntries, 512);
-                        entries = AllocatePool(sz);
-
-                        r = uefi_call_wrapper(block_io->ReadBlocks, 5,
-                                              block_io,
-                                              block_io->Media->MediaId,
-                                              h->PartitionEntryLBA,
-                                              sz, entries);
-                        if (EFI_ERROR(r))
-                                continue;
-
-                        /* Calculate CRC of entries array, too */
-                        r = BS->CalculateCrc32(&entries, sz, &crc32);
-                        if (EFI_ERROR(r) || crc32 != h->PartitionEntryArrayCRC32)
-                                continue;
-
-                        for (UINTN i = 0; i < h->NumberOfPartitionEntries; i++) {
-                                EFI_PARTITION_ENTRY *entry;
-
-                                entry = (EFI_PARTITION_ENTRY*) ((UINT8*) entries + h->SizeOfPartitionEntry * i);
-
-                                if (CompareMem(&entry->PartitionTypeGUID, XBOOTLDR_GUID, 16) == 0) {
-                                        UINT64 end;
-
-                                        /* Let's use memcpy(), in case the structs are not aligned (they really should be though) */
-                                        CopyMem(&found_partition_start, &entry->StartingLBA, sizeof(found_partition_start));
-                                        CopyMem(&end, &entry->EndingLBA, sizeof(end));
-
-                                        if (end < found_partition_start) /* Bogus? */
-                                                continue;
-
-                                        found_partition_size = end - found_partition_start + 1;
-                                        CopyMem(found_partition_signature, &entry->UniquePartitionGUID, sizeof(found_partition_signature));
-
-                                        found_partition_number = i + 1;
-                                        goto found;
-                                }
-                        }
-
-                        break; /* This GPT was fully valid, but we didn't find what we are looking for. This
-                                * means there's no reason to check the second copy of the GPT header */
-                }
-        }
-
-        return; /* Not found */
-
-found:
-        copy = DuplicateDevicePath(partition_path);
-
-        /* Patch in the data we found */
-        for (EFI_DEVICE_PATH *node = copy; !IsDevicePathEnd(node); node = NextDevicePathNode(node)) {
-                HARDDRIVE_DEVICE_PATH *hd;
-
-                if (DevicePathType(node) != MEDIA_DEVICE_PATH)
-                        continue;
-
-                if (DevicePathSubType(node) != MEDIA_HARDDRIVE_DP)
-                        continue;
-
-                hd = (HARDDRIVE_DEVICE_PATH*) node;
-                hd->PartitionNumber = found_partition_number;
-                hd->PartitionStart = found_partition_start;
-                hd->PartitionSize = found_partition_size;
-                CopyMem(hd->Signature, found_partition_signature, sizeof(hd->Signature));
-                hd->MBRType = MBR_TYPE_EFI_PARTITION_TABLE_HEADER;
-                hd->SignatureType = SIGNATURE_TYPE_GUID;
-        }
-
-        r = uefi_call_wrapper(BS->LocateDevicePath, 3, &BlockIoProtocol, &copy, &new_device);
-        if (EFI_ERROR(r))
-                return;
-
-        root_dir = LibOpenRoot(new_device);
-        if (!root_dir)
+        err = xbootldr_open(device, &new_device, &root_dir);
+        if (EFI_ERROR(err))
                 return;
 
         config_entry_add_linux(config, new_device, root_dir);
@@ -2475,9 +2307,9 @@ static VOID config_load_all_entries(
 EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) {
         _cleanup_freepool_ EFI_LOADED_IMAGE *loaded_image = NULL;
         _cleanup_(FileHandleClosep) EFI_FILE *root_dir = NULL;
+        _cleanup_(config_free) Config config = {};
         CHAR16 *loaded_image_path;
         EFI_STATUS err;
-        Config config;
         UINT64 init_usec;
         BOOLEAN menu = FALSE;
 
@@ -2592,7 +2424,6 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) {
         }
         err = EFI_SUCCESS;
 out:
-        config_free(&config);
         uefi_call_wrapper(BS->CloseProtocol, 4, image, &LoadedImageProtocol, image, NULL);
         return err;
 }
index 10a044cc926a169005a15f631fec297aa9d32984..e20615633f2716229ee9d8a7a160f695d859b6e7 100644 (file)
@@ -449,7 +449,6 @@ EFI_STATUS pack_cpio(
         if (EFI_ERROR(err))
                 return log_error_status_stall(err, L"Failed to pack cpio trailer: %r");
 
-#if ENABLE_TPM
         err = tpm_log_event(
                         tpm_pcr,
                         POINTER_TO_PHYSICAL_ADDRESS(buffer),
@@ -457,7 +456,6 @@ EFI_STATUS pack_cpio(
                         tpm_description);
         if (EFI_ERROR(err))
                 log_error_stall(L"Unable to add initrd TPM measurement for PCR %u (%s), ignoring: %r", tpm_pcr, tpm_description, err);
-#endif
 
         *ret_buffer = TAKE_PTR(buffer);
         *ret_buffer_size = buffer_size;
index fd4b9c406c1a7f51507775537a8e2898bb38f776..d8a279e826c1b5bb6150c0a3f02848e1e347f475 100644 (file)
@@ -109,6 +109,31 @@ EFI_STATUS devicetree_install(struct devicetree_state *state,
         return uefi_call_wrapper(BS->InstallConfigurationTable, 2, &EfiDtbTableGuid, PHYSICAL_ADDRESS_TO_POINTER(state->addr));
 }
 
+EFI_STATUS devicetree_install_from_memory(struct devicetree_state *state,
+                const VOID *dtb_buffer, UINTN dtb_length) {
+
+        EFI_STATUS err;
+
+        assert(state);
+        assert(dtb_buffer && dtb_length > 0);
+
+        err = LibGetSystemConfigurationTable(&EfiDtbTableGuid, &state->orig);
+        if (EFI_ERROR(err))
+                return EFI_UNSUPPORTED;
+
+        err = devicetree_allocate(state, dtb_length);
+        if (EFI_ERROR(err))
+                return err;
+
+        CopyMem(PHYSICAL_ADDRESS_TO_POINTER(state->addr), dtb_buffer, dtb_length);
+
+        err = devicetree_fixup(state, dtb_length);
+        if (EFI_ERROR(err))
+                return err;
+
+        return uefi_call_wrapper(BS->InstallConfigurationTable, 2, &EfiDtbTableGuid, PHYSICAL_ADDRESS_TO_POINTER(state->addr));
+}
+
 void devicetree_cleanup(struct devicetree_state *state) {
         EFI_STATUS err;
 
index 2839cb681c192d1c5059c53affa6501368276f38..25f93f97f9e832f5946a9eac36e6c3e2f46a9950 100644 (file)
@@ -8,4 +8,6 @@ struct devicetree_state {
 };
 
 EFI_STATUS devicetree_install(struct devicetree_state *state, EFI_FILE_HANDLE root_dir, CHAR16 *name);
+EFI_STATUS devicetree_install_from_memory(
+                struct devicetree_state *state, const VOID *dtb_buffer, UINTN dtb_length);
 void devicetree_cleanup(struct devicetree_state *state);
index 196dc52be58d80b36324ff75594a8e167acc87db..6d3c8285a15b56648f5eb3000389825c6c703e5b 100644 (file)
@@ -8,29 +8,29 @@
 
 EFI_STATUS disk_get_part_uuid(EFI_HANDLE *handle, CHAR16 uuid[static 37]) {
         EFI_DEVICE_PATH *device_path;
+        _cleanup_freepool_ EFI_DEVICE_PATH *paths = NULL;
 
         assert(handle);
 
         /* export the device path this image is started from */
         device_path = DevicePathFromHandle(handle);
-        if (device_path) {
-                _cleanup_freepool_ EFI_DEVICE_PATH *paths = NULL;
-
-                paths = UnpackDevicePath(device_path);
-                for (EFI_DEVICE_PATH *path = paths; !IsDevicePathEnd(path); path = NextDevicePathNode(path)) {
-                        HARDDRIVE_DEVICE_PATH *drive;
-
-                        if (DevicePathType(path) != MEDIA_DEVICE_PATH)
-                                continue;
-                        if (DevicePathSubType(path) != MEDIA_HARDDRIVE_DP)
-                                continue;
-                        drive = (HARDDRIVE_DEVICE_PATH *)path;
-                        if (drive->SignatureType != SIGNATURE_TYPE_GUID)
-                                continue;
-
-                        GuidToString(uuid, (EFI_GUID *)&drive->Signature);
-                        return EFI_SUCCESS;
-                }
+        if (!device_path)
+                return EFI_NOT_FOUND;
+
+        paths = UnpackDevicePath(device_path);
+        for (EFI_DEVICE_PATH *path = paths; !IsDevicePathEnd(path); path = NextDevicePathNode(path)) {
+                HARDDRIVE_DEVICE_PATH *drive;
+
+                if (DevicePathType(path) != MEDIA_DEVICE_PATH)
+                        continue;
+                if (DevicePathSubType(path) != MEDIA_HARDDRIVE_DP)
+                        continue;
+                drive = (HARDDRIVE_DEVICE_PATH *)path;
+                if (drive->SignatureType != SIGNATURE_TYPE_GUID)
+                        continue;
+
+                GuidToString(uuid, (EFI_GUID *)&drive->Signature);
+                return EFI_SUCCESS;
         }
 
         return EFI_NOT_FOUND;
index 3f6f3f75c2eab20e06ba2f186268731fd8027122..a7a99b34484c97048455d27aec2fe87bd7eb19c5 100644 (file)
@@ -8,44 +8,10 @@
 #include <efilib.h>
 
 #include "graphics.h"
+#include "missing_efi.h"
 #include "util.h"
 
-#define EFI_CONSOLE_CONTROL_GUID \
-        &(const EFI_GUID) { 0xf42f7782, 0x12e, 0x4c12, { 0x99, 0x56, 0x49, 0xf9, 0x43, 0x4, 0xf7, 0x21 } }
-
 EFI_STATUS graphics_mode(BOOLEAN on) {
-
-        struct _EFI_CONSOLE_CONTROL_PROTOCOL;
-
-        typedef enum {
-                EfiConsoleControlScreenText,
-                EfiConsoleControlScreenGraphics,
-                EfiConsoleControlScreenMaxValue,
-        } EFI_CONSOLE_CONTROL_SCREEN_MODE;
-
-        typedef EFI_STATUS (EFIAPI *EFI_CONSOLE_CONTROL_PROTOCOL_GET_MODE)(
-                struct _EFI_CONSOLE_CONTROL_PROTOCOL *This,
-                EFI_CONSOLE_CONTROL_SCREEN_MODE *Mode,
-                BOOLEAN *UgaExists,
-                BOOLEAN *StdInLocked
-        );
-
-        typedef EFI_STATUS (EFIAPI *EFI_CONSOLE_CONTROL_PROTOCOL_SET_MODE)(
-                struct _EFI_CONSOLE_CONTROL_PROTOCOL *This,
-                EFI_CONSOLE_CONTROL_SCREEN_MODE Mode
-        );
-
-        typedef EFI_STATUS (EFIAPI *EFI_CONSOLE_CONTROL_PROTOCOL_LOCK_STD_IN)(
-                struct _EFI_CONSOLE_CONTROL_PROTOCOL *This,
-                CHAR16 *Password
-        );
-
-        typedef struct _EFI_CONSOLE_CONTROL_PROTOCOL {
-                EFI_CONSOLE_CONTROL_PROTOCOL_GET_MODE GetMode;
-                EFI_CONSOLE_CONTROL_PROTOCOL_SET_MODE SetMode;
-                EFI_CONSOLE_CONTROL_PROTOCOL_LOCK_STD_IN LockStdIn;
-        } EFI_CONSOLE_CONTROL_PROTOCOL;
-
         EFI_CONSOLE_CONTROL_PROTOCOL *ConsoleControl = NULL;
         EFI_CONSOLE_CONTROL_SCREEN_MODE new;
         EFI_CONSOLE_CONTROL_SCREEN_MODE current;
diff --git a/src/boot/efi/initrd.c b/src/boot/efi/initrd.c
new file mode 100644 (file)
index 0000000..055670f
--- /dev/null
@@ -0,0 +1,147 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+
+#include <efi.h>
+#include <efilib.h>
+
+#include "initrd.h"
+#include "macro-fundamental.h"
+#include "missing_efi.h"
+
+/* extend LoadFileProtocol */
+struct initrd_loader {
+        EFI_LOAD_FILE_PROTOCOL load_file;
+        const VOID *address;
+        UINTN length;
+};
+
+/* static structure for LINUX_INITRD_MEDIA device path
+   see https://github.com/torvalds/linux/blob/v5.13/drivers/firmware/efi/libstub/efi-stub-helper.c
+ */
+static const struct {
+        VENDOR_DEVICE_PATH vendor;
+        EFI_DEVICE_PATH end;
+} _packed_ efi_initrd_device_path = {
+        .vendor = {
+                .Header = {
+                        .Type = MEDIA_DEVICE_PATH,
+                        .SubType = MEDIA_VENDOR_DP,
+                        .Length = { sizeof(efi_initrd_device_path.vendor), 0 }
+                },
+                .Guid = LINUX_INITRD_MEDIA_GUID
+        },
+        .end = {
+                .Type = END_DEVICE_PATH_TYPE,
+                .SubType = END_ENTIRE_DEVICE_PATH_SUBTYPE,
+                .Length = { sizeof(efi_initrd_device_path.end), 0 }
+        }
+};
+
+EFIAPI EFI_STATUS initrd_load_file(
+                EFI_LOAD_FILE_PROTOCOL *this,
+                EFI_DEVICE_PATH *file_path,
+                BOOLEAN boot_policy,
+                UINTN *buffer_size,
+                VOID *buffer) {
+
+        struct initrd_loader *loader;
+
+        if (!this || !buffer_size || !file_path)
+                return EFI_INVALID_PARAMETER;
+        if (boot_policy)
+                return EFI_UNSUPPORTED;
+
+        loader = (struct initrd_loader *) this;
+
+        if (loader->length == 0 || !loader->address)
+                return EFI_NOT_FOUND;
+
+        if (!buffer || *buffer_size < loader->length) {
+                *buffer_size = loader->length;
+                return EFI_BUFFER_TOO_SMALL;
+        }
+
+        CopyMem(buffer, loader->address, loader->length);
+        *buffer_size = loader->length;
+        return EFI_SUCCESS;
+}
+
+EFI_STATUS initrd_register(
+                const VOID *initrd_address,
+                UINTN initrd_length,
+                EFI_HANDLE *ret_initrd_handle) {
+
+        EFI_STATUS err;
+        EFI_DEVICE_PATH *dp = (EFI_DEVICE_PATH *) &efi_initrd_device_path;
+        EFI_HANDLE handle;
+        struct initrd_loader *loader;
+
+        assert(ret_initrd_handle);
+
+        if (!initrd_address || initrd_length == 0)
+                return EFI_SUCCESS;
+
+        /* check if a LINUX_INITRD_MEDIA_GUID DevicePath is already registed.
+           LocateDevicePath checks for the "closest DevicePath" and returns its handle,
+           where as InstallMultipleProtocolInterfaces only maches identical DevicePaths.
+         */
+        err = uefi_call_wrapper(BS->LocateDevicePath, 3, &EfiLoadFile2Protocol, &dp, &handle);
+        if (err != EFI_NOT_FOUND) /* InitrdMedia is already registered */
+                return EFI_ALREADY_STARTED;
+
+        loader = AllocatePool(sizeof(struct initrd_loader));
+        if (!loader)
+                return EFI_OUT_OF_RESOURCES;
+
+        *loader = (struct initrd_loader) {
+                .load_file.LoadFile = initrd_load_file,
+                .address = initrd_address,
+                .length = initrd_length
+        };
+
+        /* create a new handle and register the LoadFile2 protocol with the InitrdMediaPath on it */
+        err = uefi_call_wrapper(
+                        BS->InstallMultipleProtocolInterfaces, 8,
+                        ret_initrd_handle,
+                        &DevicePathProtocol, &efi_initrd_device_path,
+                        &EfiLoadFile2Protocol, loader,
+                        NULL);
+        if (EFI_ERROR(err))
+                FreePool(loader);
+
+        return err;
+}
+
+EFI_STATUS initrd_unregister(EFI_HANDLE initrd_handle) {
+        EFI_STATUS err;
+        struct initrd_loader *loader;
+
+        if (!initrd_handle)
+                return EFI_SUCCESS;
+
+        /* get the LoadFile2 protocol that we allocated earlier */
+        err = uefi_call_wrapper(
+                        BS->OpenProtocol, 6,
+                        initrd_handle, &EfiLoadFile2Protocol, (VOID **) &loader,
+                        NULL, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL);
+        if (EFI_ERROR(err))
+                return err;
+
+        /* close the handle */
+        (void) uefi_call_wrapper(
+                        BS->CloseProtocol, 4,
+                        initrd_handle, &EfiLoadFile2Protocol, NULL, NULL);
+
+        /* uninstall all protocols thus destroying the handle */
+        err = uefi_call_wrapper(
+                        BS->UninstallMultipleProtocolInterfaces, 6,
+                        initrd_handle,
+                        &DevicePathProtocol, &efi_initrd_device_path,
+                        &EfiLoadFile2Protocol, loader,
+                        NULL);
+        if (EFI_ERROR(err))
+                return err;
+
+        initrd_handle = NULL;
+        FreePool(loader);
+        return EFI_SUCCESS;
+}
diff --git a/src/boot/efi/initrd.h b/src/boot/efi/initrd.h
new file mode 100644 (file)
index 0000000..bb3a334
--- /dev/null
@@ -0,0 +1,11 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+#pragma once
+
+#include <efi.h>
+
+EFI_STATUS initrd_register(
+                const VOID *initrd_address,
+                UINTN initrd_length,
+                EFI_HANDLE *ret_initrd_handle);
+
+EFI_STATUS initrd_unregister(EFI_HANDLE initrd_handle);
index 5232a3ba40c7dd61562bec5ca634d9a5d6ea4269..98f1db24e0eea127a33382aeed147c76695744cb 100644 (file)
 /* SPDX-License-Identifier: LGPL-2.1-or-later */
 
+/*
+ * Generic Linux boot protocol using the EFI/PE entry point of the kernel. Passes
+ * initrd with the LINUX_INITRD_MEDIA_GUID DevicePath and cmdline with
+ * EFI LoadedImageProtocol.
+ *
+ * This method works for Linux 5.8 and newer on ARM/Aarch64, x86/x68_64 and RISC-V.
+ */
+
 #include <efi.h>
 #include <efilib.h>
 
+#include "initrd.h"
 #include "linux.h"
+#include "pe.h"
 #include "util.h"
 
-#ifdef __i386__
-#define __regparm0__ __attribute__((regparm(0)))
-#else
-#define __regparm0__
-#endif
+static EFI_LOADED_IMAGE * loaded_image_free(EFI_LOADED_IMAGE *img) {
+        if (!img)
+                return NULL;
+        mfree(img->LoadOptions);
+        return mfree(img);
+}
+
+static EFI_STATUS loaded_image_register(
+                const CHAR8 *cmdline, UINTN cmdline_len,
+                const VOID *linux_buffer, UINTN linux_length,
+                EFI_HANDLE *ret_image) {
+
+        EFI_LOADED_IMAGE *loaded_image = NULL;
+        EFI_STATUS err;
+
+        assert(cmdline || cmdline_len > 0);
+        assert(linux_buffer && linux_length > 0);
+        assert(ret_image);
 
-typedef VOID(*handover_f)(VOID *image, EFI_SYSTEM_TABLE *table, struct boot_params *params) __regparm0__;
+        /* create and install new LoadedImage Protocol */
+        loaded_image = AllocatePool(sizeof(EFI_LOADED_IMAGE));
+        if (!loaded_image)
+                return EFI_OUT_OF_RESOURCES;
 
-static VOID linux_efi_handover(EFI_HANDLE image, struct boot_params *params) {
-        handover_f handover;
-        UINTN start = (UINTN)params->hdr.code32_start;
+        /* provide the image base address and size */
+        *loaded_image = (EFI_LOADED_IMAGE) {
+                .ImageBase = (VOID *) linux_buffer,
+                .ImageSize = linux_length
+        };
 
-        assert(params);
+        /* if a cmdline is set convert it to UTF16 */
+        if (cmdline) {
+                loaded_image->LoadOptions = stra_to_str(cmdline);
+                if (!loaded_image->LoadOptions) {
+                        loaded_image = loaded_image_free(loaded_image);
+                        return EFI_OUT_OF_RESOURCES;
+                }
+                loaded_image->LoadOptionsSize = StrSize(loaded_image->LoadOptions);
+        }
+
+        /* install a new LoadedImage protocol. ret_handle is a new image handle */
+        err = uefi_call_wrapper(BS->InstallMultipleProtocolInterfaces, 4,
+                        ret_image,
+                        &LoadedImageProtocol, loaded_image,
+                        NULL);
+        if (EFI_ERROR(err))
+                loaded_image = loaded_image_free(loaded_image);
 
-#ifdef __x86_64__
-        asm volatile ("cli");
-        start += 512;
-#endif
-        handover = (handover_f)(start + params->hdr.handover_offset);
-        handover(image, ST, params);
+        return err;
 }
 
-EFI_STATUS linux_exec(EFI_HANDLE image,
-                      CHAR8 *cmdline, UINTN cmdline_len,
-                      UINTN linux_addr,
-                      UINTN initrd_addr, UINTN initrd_size) {
+static EFI_STATUS loaded_image_unregister(EFI_HANDLE loaded_image_handle) {
+        EFI_LOADED_IMAGE_PROTOCOL *loaded_image;
+        EFI_STATUS err;
+
+        if (!loaded_image_handle)
+                return EFI_SUCCESS;
+
+        /* get the LoadedImage protocol that we allocated earlier */
+        err = uefi_call_wrapper(
+                        BS->OpenProtocol, 6,
+                        loaded_image_handle, &LoadedImageProtocol, (VOID **) &loaded_image,
+                        NULL, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL);
+        if (EFI_ERROR(err))
+                return err;
 
-        const struct boot_params *image_params;
-        struct boot_params *boot_params;
+        /* close the handle */
+        (void) uefi_call_wrapper(
+                        BS->CloseProtocol, 4,
+                        loaded_image_handle, &LoadedImageProtocol, NULL, NULL);
+        err = uefi_call_wrapper(BS->UninstallMultipleProtocolInterfaces, 4,
+                        loaded_image_handle,
+                        &LoadedImageProtocol, loaded_image,
+                        NULL);
+        if (EFI_ERROR(err))
+                return err;
+        loaded_image_handle = NULL;
+        loaded_image = loaded_image_free(loaded_image);
+
+        return EFI_SUCCESS;
+}
+
+static inline void cleanup_initrd(EFI_HANDLE *initrd_handle) {
+        (void) initrd_unregister(*initrd_handle);
+        *initrd_handle = NULL;
+}
+
+static inline void cleanup_loaded_image(EFI_HANDLE *loaded_image_handle) {
+        (void) loaded_image_unregister(*loaded_image_handle);
+        *loaded_image_handle = NULL;
+}
+
+/* struct to call cleanup_pages */
+struct pages {
         EFI_PHYSICAL_ADDRESS addr;
-        UINT8 setup_sectors;
-        EFI_STATUS err;
+        UINTN num;
+};
 
-        assert(image);
-        assert(cmdline);
+static inline void cleanup_pages(struct pages *p) {
+        if (p->addr == 0)
+                return;
+        (void) uefi_call_wrapper(BS->FreePages, 2, p->addr, p->num);
+}
 
-        image_params = (const struct boot_params *) linux_addr;
+EFI_STATUS linux_exec(
+                EFI_HANDLE image,
+                const CHAR8 *cmdline, UINTN cmdline_len,
+                const VOID *linux_buffer, UINTN linux_length,
+                const VOID *initrd_buffer, UINTN initrd_length) {
+
+        _cleanup_(cleanup_initrd) EFI_HANDLE initrd_handle = NULL;
+        _cleanup_(cleanup_loaded_image) EFI_HANDLE loaded_image_handle = NULL;
+        UINT32 kernel_alignment, kernel_size_of_image, kernel_entry_address;
+        EFI_IMAGE_ENTRY_POINT kernel_entry;
+        _cleanup_(cleanup_pages) struct pages kernel = {};
+        VOID *new_buffer;
+        EFI_STATUS err;
 
-        if (image_params->hdr.boot_flag != 0xAA55 ||
-            image_params->hdr.header != SETUP_MAGIC ||
-            image_params->hdr.version < 0x20b ||
-            !image_params->hdr.relocatable_kernel)
-                return EFI_LOAD_ERROR;
+        assert(image);
+        assert(cmdline || cmdline_len == 0);
+        assert(linux_buffer && linux_length > 0);
+        assert(initrd_buffer || initrd_length == 0);
 
-        addr = UINT32_MAX; /* Below the 32bit boundary */
-        err = uefi_call_wrapper(
-                        BS->AllocatePages, 4,
-                        AllocateMaxAddress,
-                        EfiLoaderData,
-                        EFI_SIZE_TO_PAGES(0x4000),
-                        &addr);
+        /* get the necessary fields from the PE header */
+        err = pe_alignment_info(linux_buffer, &kernel_entry_address, &kernel_size_of_image, &kernel_alignment);
         if (EFI_ERROR(err))
                 return err;
+        /* sanity check */
+        assert(kernel_size_of_image >= linux_length);
+
+        /* Linux kernel complains if it's not loaded at a properly aligned memory address. The correct alignment
+           is provided by Linux as the SegmentAlignment in the PeOptionalHeader. Additionally the kernel needs to
+           be in a memory segment thats SizeOfImage (again from PeOptionalHeader) large, so that the Kernel has
+           space for its BSS section. SizeOfImage is always larger than linux_length, which is only the size of
+           Code, (static) Data and Headers.
+
+           Interrestingly only ARM/Aarch64 and RISC-V kernel stubs check these assertions and can even boot (with warnings)
+           if they are not met. x86 and x86_64 kernel stubs don't do checks and fail if the BSS section is too small.
+        */
+        /* allocate SizeOfImage + SectionAlignment because the new_buffer can move up to Alignment-1 bytes */
+        kernel.num = EFI_SIZE_TO_PAGES(ALIGN_TO(kernel_size_of_image, kernel_alignment) + kernel_alignment);
+        err = uefi_call_wrapper(
+                BS->AllocatePages, 4,
+                AllocateAnyPages, EfiLoaderData,
+                kernel.num, &kernel.addr);
+        if (EFI_ERROR(err))
+                return EFI_OUT_OF_RESOURCES;
+        new_buffer = PHYSICAL_ADDRESS_TO_POINTER(ALIGN_TO(kernel.addr, kernel_alignment));
+        CopyMem(new_buffer, linux_buffer, linux_length);
+        /* zero out rest of memory (probably not needed, but BSS section should be 0) */
+        SetMem((UINT8 *)new_buffer + linux_length, kernel_size_of_image - linux_length, 0);
 
-        boot_params = (struct boot_params *) PHYSICAL_ADDRESS_TO_POINTER(addr);
-        ZeroMem(boot_params, 0x4000);
-        boot_params->hdr = image_params->hdr;
-        boot_params->hdr.type_of_loader = 0xff;
-        setup_sectors = image_params->hdr.setup_sects > 0 ? image_params->hdr.setup_sects : 4;
-        boot_params->hdr.code32_start = (UINT32)linux_addr + (setup_sectors + 1) * 512;
+        /* get the entry point inside the relocated kernel */
+        kernel_entry = (EFI_IMAGE_ENTRY_POINT) ((const UINT8 *)new_buffer + kernel_entry_address);
 
-        if (cmdline) {
-                addr = 0xA0000;
-
-                err = uefi_call_wrapper(
-                                BS->AllocatePages, 4,
-                                AllocateMaxAddress,
-                                EfiLoaderData,
-                                EFI_SIZE_TO_PAGES(cmdline_len + 1),
-                                &addr);
-                if (EFI_ERROR(err))
-                        return err;
-
-                CopyMem(PHYSICAL_ADDRESS_TO_POINTER(addr), cmdline, cmdline_len);
-                ((CHAR8 *) PHYSICAL_ADDRESS_TO_POINTER(addr))[cmdline_len] = 0;
-                boot_params->hdr.cmd_line_ptr = (UINT32) addr;
-        }
+        /* register a LoadedImage Protocol in order to pass on the commandline */
+        err = loaded_image_register(cmdline, cmdline_len, new_buffer, linux_length, &loaded_image_handle);
+        if (EFI_ERROR(err))
+                return err;
 
-        boot_params->hdr.ramdisk_image = (UINT32) initrd_addr;
-        boot_params->hdr.ramdisk_size = (UINT32) initrd_size;
+        /* register a LINUX_INITRD_MEDIA DevicePath to serve the initrd */
+        err = initrd_register(initrd_buffer, initrd_length, &initrd_handle);
+        if (EFI_ERROR(err))
+                return err;
 
-        linux_efi_handover(image, boot_params);
-        return EFI_LOAD_ERROR;
+        /* call the kernel */
+        return uefi_call_wrapper(kernel_entry, 2, loaded_image_handle, ST);
 }
index 773c260b7ef81c1f779f9de2b5e2b9f15587b78b..e030e4f31ea97d3806edcb793cfc7e2b3eba4141 100644 (file)
@@ -2,89 +2,9 @@
 #pragma once
 
 #include <efi.h>
-#include "macro-fundamental.h"
 
-#define SETUP_MAGIC             0x53726448      /* "HdrS" */
-
-struct setup_header {
-        UINT8  setup_sects;
-        UINT16 root_flags;
-        UINT32 syssize;
-        UINT16 ram_size;
-        UINT16 vid_mode;
-        UINT16 root_dev;
-        UINT16 boot_flag;
-        UINT16 jump;
-        UINT32 header;
-        UINT16 version;
-        UINT32 realmode_swtch;
-        UINT16 start_sys_seg;
-        UINT16 kernel_version;
-        UINT8  type_of_loader;
-        UINT8  loadflags;
-        UINT16 setup_move_size;
-        UINT32 code32_start;
-        UINT32 ramdisk_image;
-        UINT32 ramdisk_size;
-        UINT32 bootsect_kludge;
-        UINT16 heap_end_ptr;
-        UINT8  ext_loader_ver;
-        UINT8  ext_loader_type;
-        UINT32 cmd_line_ptr;
-        UINT32 initrd_addr_max;
-        UINT32 kernel_alignment;
-        UINT8  relocatable_kernel;
-        UINT8  min_alignment;
-        UINT16 xloadflags;
-        UINT32 cmdline_size;
-        UINT32 hardware_subarch;
-        UINT64 hardware_subarch_data;
-        UINT32 payload_offset;
-        UINT32 payload_length;
-        UINT64 setup_data;
-        UINT64 pref_address;
-        UINT32 init_size;
-        UINT32 handover_offset;
-} _packed_;
-
-/* adapted from linux' bootparam.h */
-struct boot_params {
-        UINT8  screen_info[64];         // was: struct screen_info
-        UINT8  apm_bios_info[20];       // was: struct apm_bios_info
-        UINT8  _pad2[4];
-        UINT64 tboot_addr;
-        UINT8  ist_info[16];            // was: struct ist_info
-        UINT8  _pad3[16];
-        UINT8  hd0_info[16];
-        UINT8  hd1_info[16];
-        UINT8  sys_desc_table[16];      // was: struct sys_desc_table
-        UINT8  olpc_ofw_header[16];     // was: struct olpc_ofw_header
-        UINT32 ext_ramdisk_image;
-        UINT32 ext_ramdisk_size;
-        UINT32 ext_cmd_line_ptr;
-        UINT8  _pad4[116];
-        UINT8  edid_info[128];          // was: struct edid_info
-        UINT8  efi_info[32];            // was: struct efi_info
-        UINT32 alt_mem_k;
-        UINT32 scratch;
-        UINT8  e820_entries;
-        UINT8  eddbuf_entries;
-        UINT8  edd_mbr_sig_buf_entries;
-        UINT8  kbd_status;
-        UINT8  secure_boot;
-        UINT8  _pad5[2];
-        UINT8  sentinel;
-        UINT8  _pad6[1];
-        struct setup_header hdr;
-        UINT8  _pad7[0x290-0x1f1-sizeof(struct setup_header)];
-        UINT32 edd_mbr_sig_buffer[16];  // was: edd_mbr_sig_buffer[EDD_MBR_SIG_MAX]
-        UINT8  e820_table[20*128];      // was: struct boot_e820_entry e820_table[E820_MAX_ENTRIES_ZEROPAGE]
-        UINT8  _pad8[48];
-        UINT8  eddbuf[6*82];            // was: struct edd_info eddbuf[EDDMAXNR]
-        UINT8  _pad9[276];
-} _packed_;
-
-EFI_STATUS linux_exec(EFI_HANDLE image,
-                      CHAR8 *cmdline, UINTN cmdline_size,
-                      UINTN linux_addr,
-                      UINTN initrd_addr, UINTN initrd_size);
+EFI_STATUS linux_exec(
+                EFI_HANDLE image,
+                const CHAR8 *cmdline, UINTN cmdline_len,
+                const VOID *linux_buffer, UINTN linux_length,
+                const VOID *initrd_buffer, UINTN initrd_length);
diff --git a/src/boot/efi/linux_x86.c b/src/boot/efi/linux_x86.c
new file mode 100644 (file)
index 0000000..539ad72
--- /dev/null
@@ -0,0 +1,200 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+
+/*
+ * x86 specific code to for EFI handover boot protocol
+ * Linux kernels version 5.8 and newer support providing the initrd by
+ * LINUX_INITRD_MEDIA_GUID DevicePath. In order to support older kernels too,
+ * this x86 specific linux_exec function passes the initrd by setting the
+ * corresponding fields in the setup_header struct.
+ *
+ * see https://www.kernel.org/doc/html/latest/x86/boot.html
+ */
+
+#include <efi.h>
+#include <efilib.h>
+
+#include "initrd.h"
+#include "linux.h"
+#include "macro-fundamental.h"
+#include "util.h"
+
+#define SETUP_MAGIC             0x53726448      /* "HdrS" */
+
+struct setup_header {
+        UINT8  setup_sects;
+        UINT16 root_flags;
+        UINT32 syssize;
+        UINT16 ram_size;
+        UINT16 vid_mode;
+        UINT16 root_dev;
+        UINT16 boot_flag;
+        UINT16 jump;
+        UINT32 header;
+        UINT16 version;
+        UINT32 realmode_swtch;
+        UINT16 start_sys_seg;
+        UINT16 kernel_version;
+        UINT8  type_of_loader;
+        UINT8  loadflags;
+        UINT16 setup_move_size;
+        UINT32 code32_start;
+        UINT32 ramdisk_image;
+        UINT32 ramdisk_size;
+        UINT32 bootsect_kludge;
+        UINT16 heap_end_ptr;
+        UINT8  ext_loader_ver;
+        UINT8  ext_loader_type;
+        UINT32 cmd_line_ptr;
+        UINT32 initrd_addr_max;
+        UINT32 kernel_alignment;
+        UINT8  relocatable_kernel;
+        UINT8  min_alignment;
+        UINT16 xloadflags;
+        UINT32 cmdline_size;
+        UINT32 hardware_subarch;
+        UINT64 hardware_subarch_data;
+        UINT32 payload_offset;
+        UINT32 payload_length;
+        UINT64 setup_data;
+        UINT64 pref_address;
+        UINT32 init_size;
+        UINT32 handover_offset;
+} _packed_;
+
+/* adapted from linux' bootparam.h */
+struct boot_params {
+        UINT8  screen_info[64];         // was: struct screen_info
+        UINT8  apm_bios_info[20];       // was: struct apm_bios_info
+        UINT8  _pad2[4];
+        UINT64 tboot_addr;
+        UINT8  ist_info[16];            // was: struct ist_info
+        UINT8  _pad3[16];
+        UINT8  hd0_info[16];
+        UINT8  hd1_info[16];
+        UINT8  sys_desc_table[16];      // was: struct sys_desc_table
+        UINT8  olpc_ofw_header[16];     // was: struct olpc_ofw_header
+        UINT32 ext_ramdisk_image;
+        UINT32 ext_ramdisk_size;
+        UINT32 ext_cmd_line_ptr;
+        UINT8  _pad4[116];
+        UINT8  edid_info[128];          // was: struct edid_info
+        UINT8  efi_info[32];            // was: struct efi_info
+        UINT32 alt_mem_k;
+        UINT32 scratch;
+        UINT8  e820_entries;
+        UINT8  eddbuf_entries;
+        UINT8  edd_mbr_sig_buf_entries;
+        UINT8  kbd_status;
+        UINT8  secure_boot;
+        UINT8  _pad5[2];
+        UINT8  sentinel;
+        UINT8  _pad6[1];
+        struct setup_header hdr;
+        UINT8  _pad7[0x290-0x1f1-sizeof(struct setup_header)];
+        UINT32 edd_mbr_sig_buffer[16];  // was: edd_mbr_sig_buffer[EDD_MBR_SIG_MAX]
+        UINT8  e820_table[20*128];      // was: struct boot_e820_entry e820_table[E820_MAX_ENTRIES_ZEROPAGE]
+        UINT8  _pad8[48];
+        UINT8  eddbuf[6*82];            // was: struct edd_info eddbuf[EDDMAXNR]
+        UINT8  _pad9[276];
+} _packed_;
+
+#ifdef __i386__
+#define __regparm0__ __attribute__((regparm(0)))
+#else
+#define __regparm0__
+#endif
+
+typedef VOID(*handover_f)(VOID *image, EFI_SYSTEM_TABLE *table, struct boot_params *params) __regparm0__;
+
+static VOID linux_efi_handover(EFI_HANDLE image, struct boot_params *params) {
+        handover_f handover;
+        UINTN start = (UINTN)params->hdr.code32_start;
+
+        assert(params);
+
+#ifdef __x86_64__
+        asm volatile ("cli");
+        start += 512;
+#endif
+        handover = (handover_f)(start + params->hdr.handover_offset);
+        handover(image, ST, params);
+}
+
+EFI_STATUS linux_exec(
+                EFI_HANDLE image,
+                const CHAR8 *cmdline, UINTN cmdline_len,
+                const VOID *linux_buffer, UINTN linux_length,
+                const VOID *initrd_buffer, UINTN initrd_length) {
+
+        const struct boot_params *image_params;
+        struct boot_params *boot_params;
+        EFI_HANDLE initrd_handle = NULL;
+        EFI_PHYSICAL_ADDRESS addr;
+        UINT8 setup_sectors;
+        EFI_STATUS err;
+
+        assert(image);
+        assert(cmdline || cmdline_len == 0);
+        assert(linux_buffer);
+        assert(initrd_buffer || initrd_length == 0);
+
+        image_params = (const struct boot_params *) linux_buffer;
+
+        if (image_params->hdr.boot_flag != 0xAA55 ||
+            image_params->hdr.header != SETUP_MAGIC ||
+            image_params->hdr.version < 0x20b ||
+            !image_params->hdr.relocatable_kernel)
+                return EFI_LOAD_ERROR;
+
+        addr = UINT32_MAX; /* Below the 32bit boundary */
+        err = uefi_call_wrapper(
+                        BS->AllocatePages, 4,
+                        AllocateMaxAddress,
+                        EfiLoaderData,
+                        EFI_SIZE_TO_PAGES(0x4000),
+                        &addr);
+        if (EFI_ERROR(err))
+                return err;
+
+        boot_params = (struct boot_params *) PHYSICAL_ADDRESS_TO_POINTER(addr);
+        ZeroMem(boot_params, 0x4000);
+        boot_params->hdr = image_params->hdr;
+        boot_params->hdr.type_of_loader = 0xff;
+        setup_sectors = image_params->hdr.setup_sects > 0 ? image_params->hdr.setup_sects : 4;
+        boot_params->hdr.code32_start = (UINT32) POINTER_TO_PHYSICAL_ADDRESS(linux_buffer) + (setup_sectors + 1) * 512;
+
+        if (cmdline) {
+                addr = 0xA0000;
+
+                err = uefi_call_wrapper(
+                                BS->AllocatePages, 4,
+                                AllocateMaxAddress,
+                                EfiLoaderData,
+                                EFI_SIZE_TO_PAGES(cmdline_len + 1),
+                                &addr);
+                if (EFI_ERROR(err))
+                        return err;
+
+                CopyMem(PHYSICAL_ADDRESS_TO_POINTER(addr), cmdline, cmdline_len);
+                ((CHAR8 *) PHYSICAL_ADDRESS_TO_POINTER(addr))[cmdline_len] = 0;
+                boot_params->hdr.cmd_line_ptr = (UINT32) addr;
+        }
+
+        /* Providing the initrd via LINUX_INITRD_MEDIA_GUID is only supported by Linux 5.8+ (5.7+ on ARM64).
+           Until supported kernels become more established, we continue to set ramdisk in the handover struct.
+           This value is overridden by kernels that support LINUX_INITRD_MEDIA_GUID.
+           If you need to know which protocol was used by the kernel, pass "efi=debug" to the kernel,
+           this will print a line when InitrdMediaGuid was successfully used to load the initrd.
+         */
+        boot_params->hdr.ramdisk_image = (UINT32) POINTER_TO_PHYSICAL_ADDRESS(initrd_buffer);
+        boot_params->hdr.ramdisk_size = (UINT32) initrd_length;
+
+        /* register LINUX_INITRD_MEDIA_GUID */
+        err = initrd_register(initrd_buffer, initrd_length, &initrd_handle);
+        if (EFI_ERROR(err))
+                return err;
+        linux_efi_handover(image, boot_params);
+        (void) initrd_unregister(initrd_handle);
+        initrd_handle = NULL;
+        return EFI_LOAD_ERROR;
+}
index 81b750d5d358dd2f2d9eb84813c300891358427c..e3e13fec0412105aa75fa9e2367dea4784a1306f 100644 (file)
@@ -15,10 +15,12 @@ efi_headers = files('''
         shim.h
         splash.h
         util.h
+        xbootldr.h
 '''.split())
 
 common_sources = '''
         assert.c
+        devicetree.c
         disk.c
         graphics.c
         measure.c
@@ -30,14 +32,14 @@ common_sources = '''
 systemd_boot_sources = '''
         boot.c
         console.c
-        devicetree.c
         drivers.c
         random-seed.c
         shim.c
+        xbootldr.c
 '''.split()
 
 stub_sources = '''
-        linux.c
+        initrd.c
         splash.c
         stub.c
         cpio.c
@@ -206,6 +208,11 @@ if have_gnu_efi
                 '-include', efi_config_h,
                 '-include', version_h,
         ]
+        if ['ia32', 'x86_64'].contains(efi_arch)
+                stub_sources += 'linux_x86.c'
+        else
+                stub_sources += 'linux.c'
+        endif
         if efi_arch == 'x86_64'
                 compile_args += ['-mno-red-zone',
                                  '-mno-sse',
index badf0017ad420e6bb0de9088678f1164715fa461..e3e0b978ef80ba36ef4e83afcad7ff7ba95a21ea 100644 (file)
@@ -161,6 +161,10 @@ struct _EFI_DT_FIXUP_PROTOCOL {
         EFI_DT_FIXUP   Fixup;
 };
 
+#endif
+
+#ifndef EFI_TCG_GUID
+
 #define EFI_TCG_GUID \
         &(const EFI_GUID) { 0xf541796d, 0xa62e, 0x4954, { 0xa7, 0x75, 0x95, 0x84, 0xf6, 0x1b, 0x9c, 0xdd } }
 
@@ -256,6 +260,10 @@ typedef struct _EFI_TCG {
         EFI_TCG_HASH_LOG_EXTEND_EVENT HashLogExtendEvent;
 } EFI_TCG;
 
+#endif
+
+#ifndef EFI_TCG2_GUID
+
 #define EFI_TCG2_GUID \
         &(const EFI_GUID) { 0x607f766c, 0x7455, 0x42be, { 0x93, 0x0b, 0xe4, 0xd7, 0x6d, 0xb2, 0x72, 0x0f } }
 
@@ -331,3 +339,90 @@ typedef struct tdEFI_TCG2_PROTOCOL {
 } EFI_TCG2;
 
 #endif
+
+#ifndef EFI_LOAD_FILE2_PROTOCOL_GUID
+#define EFI_LOAD_FILE2_PROTOCOL_GUID \
+        {0x4006c0c1, 0xfcb3, 0x403e, {0x99, 0x6d, 0x4a, 0x6c, 0x87, 0x24, 0xe0, 0x6d} }
+#define EfiLoadFile2Protocol ((EFI_GUID)EFI_LOAD_FILE2_PROTOCOL_GUID)
+#endif
+
+#define LINUX_INITRD_MEDIA_GUID \
+        {0x5568e427, 0x68fc, 0x4f3d, {0xac, 0x74, 0xca, 0x55, 0x52, 0x31, 0xcc, 0x68} }
+
+/* UEFI Platform Initialization (Vol2: DXE) */
+#ifndef SECURITY_PROTOCOL_GUID
+
+#define SECURITY_PROTOCOL_GUID \
+        &(const EFI_GUID) { 0xa46423e3, 0x4617, 0x49f1, { 0xb9, 0xff, 0xd1, 0xbf, 0xa9, 0x11, 0x58, 0x39 } }
+#define SECURITY_PROTOCOL2_GUID \
+        &(const EFI_GUID) { 0x94ab2f58, 0x1438, 0x4ef1, { 0x91, 0x52, 0x18, 0x94, 0x1a, 0x3a, 0x0e, 0x68 } }
+
+struct _EFI_SECURITY2_PROTOCOL;
+struct _EFI_SECURITY_PROTOCOL;
+struct _EFI_DEVICE_PATH_PROTOCOL;
+
+typedef struct _EFI_SECURITY2_PROTOCOL EFI_SECURITY2_PROTOCOL;
+typedef struct _EFI_SECURITY_PROTOCOL EFI_SECURITY_PROTOCOL;
+typedef struct _EFI_DEVICE_PATH_PROTOCOL EFI_DEVICE_PATH_PROTOCOL;
+
+typedef EFI_STATUS (EFIAPI *EFI_SECURITY_FILE_AUTHENTICATION_STATE) (
+        const EFI_SECURITY_PROTOCOL *This,
+        UINT32 AuthenticationStatus,
+        const EFI_DEVICE_PATH_PROTOCOL *File
+);
+
+typedef EFI_STATUS (EFIAPI *EFI_SECURITY2_FILE_AUTHENTICATION) (
+        const EFI_SECURITY2_PROTOCOL *This,
+        const EFI_DEVICE_PATH_PROTOCOL *DevicePath,
+        VOID *FileBuffer,
+        UINTN FileSize,
+        BOOLEAN  BootPolicy
+);
+
+struct _EFI_SECURITY2_PROTOCOL {
+        EFI_SECURITY2_FILE_AUTHENTICATION FileAuthentication;
+};
+
+struct _EFI_SECURITY_PROTOCOL {
+        EFI_SECURITY_FILE_AUTHENTICATION_STATE  FileAuthenticationState;
+};
+
+#endif
+
+#ifndef EFI_CONSOLE_CONTROL_GUID
+
+#define EFI_CONSOLE_CONTROL_GUID \
+        &(const EFI_GUID) { 0xf42f7782, 0x12e, 0x4c12, { 0x99, 0x56, 0x49, 0xf9, 0x43, 0x4, 0xf7, 0x21 } }
+
+struct _EFI_CONSOLE_CONTROL_PROTOCOL;
+
+typedef enum {
+        EfiConsoleControlScreenText,
+        EfiConsoleControlScreenGraphics,
+        EfiConsoleControlScreenMaxValue,
+} EFI_CONSOLE_CONTROL_SCREEN_MODE;
+
+typedef EFI_STATUS (EFIAPI *EFI_CONSOLE_CONTROL_PROTOCOL_GET_MODE)(
+        struct _EFI_CONSOLE_CONTROL_PROTOCOL *This,
+        EFI_CONSOLE_CONTROL_SCREEN_MODE *Mode,
+        BOOLEAN *UgaExists,
+        BOOLEAN *StdInLocked
+);
+
+typedef EFI_STATUS (EFIAPI *EFI_CONSOLE_CONTROL_PROTOCOL_SET_MODE)(
+        struct _EFI_CONSOLE_CONTROL_PROTOCOL *This,
+        EFI_CONSOLE_CONTROL_SCREEN_MODE Mode
+);
+
+typedef EFI_STATUS (EFIAPI *EFI_CONSOLE_CONTROL_PROTOCOL_LOCK_STD_IN)(
+        struct _EFI_CONSOLE_CONTROL_PROTOCOL *This,
+        CHAR16 *Password
+);
+
+typedef struct _EFI_CONSOLE_CONTROL_PROTOCOL {
+        EFI_CONSOLE_CONTROL_PROTOCOL_GET_MODE GetMode;
+        EFI_CONSOLE_CONTROL_PROTOCOL_SET_MODE SetMode;
+        EFI_CONSOLE_CONTROL_PROTOCOL_LOCK_STD_IN LockStdIn;
+} EFI_CONSOLE_CONTROL_PROTOCOL;
+
+#endif
index 04b4504c2ee3babdbd6ff2714c8b8445b55ea804..1309eb13a26758171f261dda4b54d0a0da85c623 100644 (file)
@@ -56,10 +56,46 @@ struct CoffFileHeader {
         UINT16  Characteristics;
 } _packed_;
 
+#define OPTHDR32_MAGIC 0x10B /* PE32  OptionalHeader */
+#define OPTHDR64_MAGIC 0x20B /* PE32+ OptionalHeader */
+
+struct PeOptionalHeader {
+        UINT16  Magic;
+        UINT8   LinkerMajor;
+        UINT8   LinkerMinor;
+        UINT32  SizeOfCode;
+        UINT32  SizeOfInitializedData;
+        UINT32  SizeOfUninitializeData;
+        UINT32  AddressOfEntryPoint;
+        UINT32  BaseOfCode;
+        union {
+                struct { /* PE32 */
+                        UINT32 BaseOfData;
+                        UINT32 ImageBase32;
+                };
+                UINT64 ImageBase64; /* PE32+ */
+        };
+        UINT32 SectionAlignment;
+        UINT32 FileAlignment;
+        UINT16 MajorOperatingSystemVersion;
+        UINT16 MinorOperatingSystemVersion;
+        UINT16 MajorImageVersion;
+        UINT16 MinorImageVersion;
+        UINT16 MajorSubsystemVersion;
+        UINT16 MinorSubsystemVersion;
+        UINT32 Win32VersionValue;
+        UINT32 SizeOfImage;
+        UINT32 SizeOfHeaders;
+        UINT32 CheckSum;
+        UINT16 Subsystem;
+        UINT16 DllCharacteristics;
+        /* fields with different sizes for 32/64 omitted */
+} _packed_;
+
 struct PeFileHeader {
         UINT8   Magic[4];
         struct CoffFileHeader FileHeader;
-        /* OptionalHeader omitted */
+        struct PeOptionalHeader OptionalHeader;
 } _packed_;
 
 struct PeSectionHeader {
@@ -91,7 +127,7 @@ static inline BOOLEAN verify_pe(const struct PeFileHeader *pe) {
 static inline UINTN section_table_offset(const struct DosFileHeader *dos, const struct PeFileHeader *pe) {
         assert(dos);
         assert(pe);
-        return dos->ExeHeader + sizeof(struct PeFileHeader) + pe->FileHeader.SizeOfOptionalHeader;
+        return dos->ExeHeader + OFFSETOF(struct PeFileHeader, OptionalHeader) + pe->FileHeader.SizeOfOptionalHeader;
 }
 
 static VOID locate_sections(
@@ -122,6 +158,41 @@ static VOID locate_sections(
         }
 }
 
+EFI_STATUS pe_alignment_info(
+                const VOID *base,
+                UINT32 *ret_entry_point_address,
+                UINT32 *ret_size_of_image,
+                UINT32 *ret_section_alignment) {
+
+        const struct DosFileHeader *dos;
+        const struct PeFileHeader *pe;
+
+        assert(base);
+        assert(ret_entry_point_address);
+        assert(ret_size_of_image);
+        assert(ret_section_alignment);
+
+        dos = (const struct DosFileHeader *) base;
+        if (!verify_dos(dos))
+                return EFI_LOAD_ERROR;
+
+        pe = (const struct PeFileHeader*) ((const UINT8 *)base + dos->ExeHeader);
+        if (!verify_pe(pe))
+                return EFI_LOAD_ERROR;
+
+        *ret_entry_point_address = pe->OptionalHeader.AddressOfEntryPoint;
+
+        if (pe->OptionalHeader.Magic == OPTHDR32_MAGIC) {
+                *ret_size_of_image = pe->OptionalHeader.SizeOfImage;
+                *ret_section_alignment = pe->OptionalHeader.SectionAlignment;
+        } else if (pe->OptionalHeader.Magic == OPTHDR64_MAGIC) {
+                *ret_size_of_image = pe->OptionalHeader.SizeOfImage;
+                *ret_section_alignment = pe->OptionalHeader.SectionAlignment;
+        } else
+                return EFI_UNSUPPORTED;
+        return EFI_SUCCESS;
+}
+
 EFI_STATUS pe_memory_locate_sections(
                 const CHAR8 *base,
                 const CHAR8 **sections,
index e35521122353571a63e7b85b64586b5f09b4547f..438cfe1b6135dfd8b39017d82da776f839cf52e8 100644 (file)
@@ -15,3 +15,9 @@ EFI_STATUS pe_file_locate_sections(
                 const CHAR8 **sections,
                 UINTN *offsets,
                 UINTN *sizes);
+
+EFI_STATUS pe_alignment_info(
+                const VOID *base,
+                UINT32 *ret_entry_point_address,
+                UINT32 *ret_size_of_image,
+                UINT32 *ret_section_alignment);
index e3fb073fdd9de45faaddf12635047f229cdfe492..9fcc45403e591e54752a58c50395cae962b67112 100644 (file)
@@ -11,6 +11,7 @@
 #include <efi.h>
 #include <efilib.h>
 
+#include "missing_efi.h"
 #include "util.h"
 #include "shim.h"
 
@@ -31,10 +32,6 @@ struct ShimLock {
 };
 
 #define SIMPLE_FS_GUID &(const EFI_GUID) SIMPLE_FILE_SYSTEM_PROTOCOL
-#define SECURITY_PROTOCOL_GUID \
-        &(const EFI_GUID) { 0xa46423e3, 0x4617, 0x49f1, { 0xb9, 0xff, 0xd1, 0xbf, 0xa9, 0x11, 0x58, 0x39 } }
-#define SECURITY_PROTOCOL2_GUID \
-        &(const EFI_GUID) { 0x94ab2f58, 0x1438, 0x4ef1, { 0x91, 0x52, 0x18, 0x94, 0x1a, 0x3a, 0x0e, 0x68 } }
 #define SHIM_LOCK_GUID \
         &(const EFI_GUID) { 0x605dab50, 0xe046, 0x4300, { 0xab, 0xb6, 0x3d, 0xd8, 0x10, 0xdd, 0x8b, 0x23 } }
 
@@ -59,39 +56,6 @@ static BOOLEAN shim_validate(VOID *data, UINT32 size) {
         return shim_lock->shim_verify(data, size) == EFI_SUCCESS;
 }
 
-/*
- * See the UEFI Platform Initialization manual (Vol2: DXE) for this
- */
-struct _EFI_SECURITY2_PROTOCOL;
-struct _EFI_SECURITY_PROTOCOL;
-struct _EFI_DEVICE_PATH_PROTOCOL;
-
-typedef struct _EFI_SECURITY2_PROTOCOL EFI_SECURITY2_PROTOCOL;
-typedef struct _EFI_SECURITY_PROTOCOL EFI_SECURITY_PROTOCOL;
-typedef struct _EFI_DEVICE_PATH_PROTOCOL EFI_DEVICE_PATH_PROTOCOL;
-
-typedef EFI_STATUS (EFIAPI *EFI_SECURITY_FILE_AUTHENTICATION_STATE) (
-        const EFI_SECURITY_PROTOCOL *This,
-        UINT32 AuthenticationStatus,
-        const EFI_DEVICE_PATH_PROTOCOL *File
-);
-
-typedef EFI_STATUS (EFIAPI *EFI_SECURITY2_FILE_AUTHENTICATION) (
-        const EFI_SECURITY2_PROTOCOL *This,
-        const EFI_DEVICE_PATH_PROTOCOL *DevicePath,
-        VOID *FileBuffer,
-        UINTN FileSize,
-        BOOLEAN  BootPolicy
-);
-
-struct _EFI_SECURITY2_PROTOCOL {
-        EFI_SECURITY2_FILE_AUTHENTICATION FileAuthentication;
-};
-
-struct _EFI_SECURITY_PROTOCOL {
-        EFI_SECURITY_FILE_AUTHENTICATION_STATE  FileAuthenticationState;
-};
-
 /* Handle to the original authenticator for security1 protocol */
 static EFI_SECURITY_FILE_AUTHENTICATION_STATE esfas = NULL;
 
index dad0f6133538063ab1119b8504451b6a9cdde12c..01774d1fd53dd7d395bfc5a9ee9e02b4ab23279c 100644 (file)
@@ -4,6 +4,7 @@
 #include <efilib.h>
 
 #include "cpio.h"
+#include "devicetree.h"
 #include "disk.h"
 #include "graphics.h"
 #include "linux.h"
@@ -14,7 +15,7 @@
 #include "util.h"
 
 /* magic string to find in the binary image */
-static const char __attribute__((used)) magic[] = "#### LoaderInfo: systemd-stub " GIT_VERSION " ####";
+_used_ _section_(".sdmagic") static const char magic[] = "#### LoaderInfo: systemd-stub " GIT_VERSION " ####";
 
 static EFI_STATUS combine_initrd(
                 EFI_PHYSICAL_ADDRESS initrd_base, UINTN initrd_size,
@@ -141,6 +142,7 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) {
                 SECTION_LINUX,
                 SECTION_INITRD,
                 SECTION_SPLASH,
+                SECTION_DTB,
                 _SECTION_MAX,
         };
 
@@ -149,12 +151,15 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) {
                 [SECTION_LINUX]   = (const CHAR8*) ".linux",
                 [SECTION_INITRD]  = (const CHAR8*) ".initrd",
                 [SECTION_SPLASH]  = (const CHAR8*) ".splash",
+                [SECTION_DTB]     = (const CHAR8*) ".dtb",
                 NULL,
         };
 
-        UINTN cmdline_len = 0, initrd_size, credential_initrd_size = 0, sysext_initrd_size = 0;
+        UINTN cmdline_len = 0, linux_size, initrd_size, dt_size;
+        UINTN credential_initrd_size = 0, sysext_initrd_size = 0;
         _cleanup_freepool_ VOID *credential_initrd = NULL, *sysext_initrd = NULL;
-        EFI_PHYSICAL_ADDRESS linux_base, initrd_base;
+        EFI_PHYSICAL_ADDRESS linux_base, initrd_base, dt_base;
+        _cleanup_(devicetree_cleanup) struct devicetree_state dt_state = {};
         EFI_LOADED_IMAGE *loaded_image;
         UINTN addrs[_SECTION_MAX] = {};
         UINTN szs[_SECTION_MAX] = {};
@@ -222,11 +227,15 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) {
                          &sysext_initrd,
                          &sysext_initrd_size);
 
+        linux_size = szs[SECTION_LINUX];
         linux_base = POINTER_TO_PHYSICAL_ADDRESS(loaded_image->ImageBase) + addrs[SECTION_LINUX];
 
         initrd_size = szs[SECTION_INITRD];
         initrd_base = initrd_size != 0 ? POINTER_TO_PHYSICAL_ADDRESS(loaded_image->ImageBase) + addrs[SECTION_INITRD] : 0;
 
+        dt_size = szs[SECTION_DTB];
+        dt_base = dt_size != 0 ? POINTER_TO_PHYSICAL_ADDRESS(loaded_image->ImageBase) + addrs[SECTION_DTB] : 0;
+
         if (credential_initrd || sysext_initrd) {
                 /* If we have generated initrds dynamically, let's combine them with the built-in initrd. */
                 err = combine_initrd(
@@ -249,7 +258,16 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) {
                 }
         }
 
-        err = linux_exec(image, cmdline, cmdline_len, linux_base, initrd_base, initrd_size);
+        if (dt_size > 0) {
+                err = devicetree_install_from_memory(
+                                &dt_state, PHYSICAL_ADDRESS_TO_POINTER(dt_base), dt_size);
+                if (EFI_ERROR(err))
+                        log_error_stall(L"Error loading embedded devicetree: %r", err);
+        }
+
+        err = linux_exec(image, cmdline, cmdline_len,
+                         PHYSICAL_ADDRESS_TO_POINTER(linux_base), linux_size,
+                         PHYSICAL_ADDRESS_TO_POINTER(initrd_base), initrd_size);
         graphics_mode(FALSE);
         return log_error_status_stall(err, L"Execution of embedded linux image failed: %r", err);
 }
diff --git a/src/boot/efi/xbootldr.c b/src/boot/efi/xbootldr.c
new file mode 100644 (file)
index 0000000..ef7ca6c
--- /dev/null
@@ -0,0 +1,306 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+
+#include <efi.h>
+#include <efigpt.h>
+#include <efilib.h>
+
+#include "util.h"
+#include "xbootldr.h"
+
+union GptHeaderBuffer {
+        EFI_PARTITION_TABLE_HEADER gpt_header;
+        uint8_t space[((sizeof(EFI_PARTITION_TABLE_HEADER) + 511) / 512) * 512];
+};
+
+static EFI_DEVICE_PATH *path_parent(EFI_DEVICE_PATH *path, EFI_DEVICE_PATH *node) {
+        EFI_DEVICE_PATH *parent;
+        UINTN len;
+
+        assert(path);
+        assert(node);
+
+        len = (UINT8*) NextDevicePathNode(node) - (UINT8*) path;
+        parent = (EFI_DEVICE_PATH*) AllocatePool(len + sizeof(EFI_DEVICE_PATH));
+        if (!parent)
+                return NULL;
+
+        CopyMem(parent, path, len);
+        CopyMem((UINT8*) parent + len, EndDevicePath, sizeof(EFI_DEVICE_PATH));
+
+        return parent;
+}
+
+static BOOLEAN verify_gpt(union GptHeaderBuffer *gpt_header_buffer, EFI_LBA lba_expected) {
+        EFI_PARTITION_TABLE_HEADER *h;
+        UINT32 crc32, crc32_saved;
+        EFI_STATUS err;
+
+        assert(gpt_header_buffer);
+
+        h = &gpt_header_buffer->gpt_header;
+
+        /* Some superficial validation of the GPT header */
+        if(CompareMem(&h->Header.Signature, "EFI PART", sizeof(h->Header.Signature) != 0))
+                return FALSE;
+
+        if (h->Header.HeaderSize < 92 || h->Header.HeaderSize > 512)
+                return FALSE;
+
+        if (h->Header.Revision != 0x00010000U)
+                return FALSE;
+
+        /* Calculate CRC check */
+        crc32_saved = h->Header.CRC32;
+        h->Header.CRC32 = 0;
+        err = BS->CalculateCrc32(gpt_header_buffer, h->Header.HeaderSize, &crc32);
+        h->Header.CRC32 = crc32_saved;
+        if (EFI_ERROR(err) || crc32 != crc32_saved)
+                return FALSE;
+
+        if (h->MyLBA != lba_expected)
+                return FALSE;
+
+        if (h->SizeOfPartitionEntry < sizeof(EFI_PARTITION_ENTRY))
+                return FALSE;
+
+        if (h->NumberOfPartitionEntries <= 0 || h->NumberOfPartitionEntries > 1024)
+                return FALSE;
+
+        /* overflow check */
+        if (h->SizeOfPartitionEntry > UINTN_MAX / h->NumberOfPartitionEntries)
+                return FALSE;
+
+        return TRUE;
+}
+
+static EFI_STATUS try_gpt(
+                EFI_BLOCK_IO *block_io,
+                EFI_LBA lba,
+                EFI_LBA *ret_backup_lba, /* May be changed even on error! */
+                UINT32 *ret_part_number,
+                UINT64 *ret_part_start,
+                UINT64 *ret_part_size,
+                EFI_GUID *ret_part_uuid) {
+
+        _cleanup_freepool_ EFI_PARTITION_ENTRY *entries = NULL;
+        union GptHeaderBuffer gpt;
+        EFI_STATUS err;
+        UINT32 crc32;
+        UINTN size;
+
+        assert(block_io);
+        assert(ret_part_number);
+        assert(ret_part_start);
+        assert(ret_part_size);
+        assert(ret_part_uuid);
+
+        /* Read the GPT header */
+        err = uefi_call_wrapper(
+                        block_io->ReadBlocks, 5,
+                        block_io,
+                        block_io->Media->MediaId,
+                        lba,
+                        sizeof(gpt), &gpt);
+        if (EFI_ERROR(err))
+                return err;
+
+        /* Indicate the location of backup LBA even if the rest of the header is corrupt. */
+        if (ret_backup_lba)
+                *ret_backup_lba = gpt.gpt_header.AlternateLBA;
+
+        if (!verify_gpt(&gpt, lba))
+                return EFI_NOT_FOUND;
+
+        /* Now load the GPT entry table */
+        size = ALIGN_TO((UINTN) gpt.gpt_header.SizeOfPartitionEntry * (UINTN) gpt.gpt_header.NumberOfPartitionEntries, 512);
+        entries = AllocatePool(size);
+        if (!entries)
+                return EFI_OUT_OF_RESOURCES;
+
+        err = uefi_call_wrapper(
+                        block_io->ReadBlocks, 5,
+                        block_io,
+                        block_io->Media->MediaId,
+                        gpt.gpt_header.PartitionEntryLBA,
+                        size, entries);
+        if (EFI_ERROR(err))
+                return err;
+
+        /* Calculate CRC of entries array, too */
+        err = BS->CalculateCrc32(entries, size, &crc32);
+        if (EFI_ERROR(err) || crc32 != gpt.gpt_header.PartitionEntryArrayCRC32)
+                return EFI_CRC_ERROR;
+
+        /* Now we can finally look for xbootloader partitions. */
+        for (UINTN i = 0; i < gpt.gpt_header.NumberOfPartitionEntries; i++) {
+                EFI_PARTITION_ENTRY *entry;
+                EFI_LBA start, end;
+
+                entry = (EFI_PARTITION_ENTRY*) ((UINT8*) entries + gpt.gpt_header.SizeOfPartitionEntry * i);
+
+                if (CompareMem(&entry->PartitionTypeGUID, XBOOTLDR_GUID, sizeof(entry->PartitionTypeGUID)) != 0)
+                        continue;
+
+                /* Let's use memcpy(), in case the structs are not aligned (they really should be though) */
+                CopyMem(&start, &entry->StartingLBA, sizeof(start));
+                CopyMem(&end, &entry->EndingLBA, sizeof(end));
+
+                if (end < start) /* Bogus? */
+                        continue;
+
+                *ret_part_number = i + 1;
+                *ret_part_start = start;
+                *ret_part_size = end - start + 1;
+                CopyMem(ret_part_uuid, &entry->UniquePartitionGUID, sizeof(*ret_part_uuid));
+
+                return EFI_SUCCESS;
+        }
+
+        /* This GPT was fully valid, but we didn't find what we are looking for. This
+         * means there's no reason to check the second copy of the GPT header */
+        return EFI_NOT_FOUND;
+}
+
+static EFI_STATUS find_device(
+                EFI_HANDLE *device,
+                EFI_DEVICE_PATH **ret_device_path,
+                UINT32 *ret_part_number,
+                UINT64 *ret_part_start,
+                UINT64 *ret_part_size,
+                EFI_GUID *ret_part_uuid) {
+
+        EFI_DEVICE_PATH *partition_path;
+        EFI_STATUS err;
+
+        assert(device);
+        assert(ret_device_path);
+        assert(ret_part_number);
+        assert(ret_part_start);
+        assert(ret_part_size);
+        assert(ret_part_uuid);
+
+        partition_path = DevicePathFromHandle(device);
+        if (!partition_path)
+                return EFI_NOT_FOUND;
+
+        for (EFI_DEVICE_PATH *node = partition_path; !IsDevicePathEnd(node); node = NextDevicePathNode(node)) {
+                _cleanup_freepool_ EFI_DEVICE_PATH *disk_path = NULL;
+                EFI_HANDLE disk_handle;
+                EFI_BLOCK_IO *block_io;
+                EFI_DEVICE_PATH *p;
+
+                /* First, Let's look for the SCSI/SATA/USB/… device path node, i.e. one above the media
+                 * devices */
+                if (DevicePathType(node) != MESSAGING_DEVICE_PATH)
+                        continue;
+
+                /* Determine the device path one level up */
+                disk_path = p = path_parent(partition_path, node);
+                if (!disk_path)
+                        continue;
+
+                err = uefi_call_wrapper(BS->LocateDevicePath, 3, &BlockIoProtocol, &p, &disk_handle);
+                if (EFI_ERROR(err))
+                        continue;
+
+                err = uefi_call_wrapper(BS->HandleProtocol, 3, disk_handle, &BlockIoProtocol, (VOID **)&block_io);
+                if (EFI_ERROR(err))
+                        continue;
+
+                /* Filter out some block devices early. (We only care about block devices that aren't
+                 * partitions themselves â€” we look for GPT partition tables to parse after all â€”, and only
+                 * those which contain a medium and have at least 2 blocks.) */
+                if (block_io->Media->LogicalPartition ||
+                    !block_io->Media->MediaPresent ||
+                    block_io->Media->LastBlock <= 1)
+                        continue;
+
+                /* Try several copies of the GPT header, in case one is corrupted */
+                EFI_LBA backup_lba = 0;
+                for (UINTN nr = 0; nr < 3; nr++) {
+                        EFI_LBA lba;
+
+                        /* Read the first copy at LBA 1 and then try the backup GPT header pointed
+                         * to by the first header if that one was corrupted. As a last resort,
+                         * try the very last LBA of this block device. */
+                        if (nr == 0)
+                                lba = 1;
+                        else if (nr == 1 && backup_lba != 0)
+                                lba = backup_lba;
+                        else if (nr == 2 && backup_lba != block_io->Media->LastBlock)
+                                lba = block_io->Media->LastBlock;
+                        else
+                                continue;
+
+                        err = try_gpt(
+                                block_io, lba,
+                                nr == 0 ? &backup_lba : NULL, /* Only get backup LBA location from first GPT header. */
+                                ret_part_number,
+                                ret_part_start,
+                                ret_part_size,
+                                ret_part_uuid);
+                        if (!EFI_ERROR(err)) {
+                                *ret_device_path = DuplicateDevicePath(partition_path);
+                                if (!*ret_device_path)
+                                        return EFI_OUT_OF_RESOURCES;
+                                return EFI_SUCCESS;
+                        }
+
+                        /* GPT was valid but no XBOOT loader partition found. */
+                        if (err == EFI_NOT_FOUND)
+                                break;
+                }
+        }
+
+        /* No xbootloader partition found */
+        return EFI_NOT_FOUND;
+}
+
+EFI_STATUS xbootldr_open(EFI_HANDLE *device, EFI_HANDLE *ret_device, EFI_FILE **ret_root_dir) {
+        _cleanup_freepool_ EFI_DEVICE_PATH *partition_path = NULL;
+        UINT32 part_number = UINT32_MAX;
+        UINT64 part_start = UINT64_MAX, part_size = UINT64_MAX;
+        EFI_HANDLE new_device;
+        EFI_FILE *root_dir;
+        EFI_GUID part_uuid;
+        EFI_STATUS err;
+
+        assert(device);
+        assert(ret_device);
+        assert(ret_root_dir);
+
+        err = find_device(device, &partition_path, &part_number, &part_start, &part_size, &part_uuid);
+        if (EFI_ERROR(err))
+                return err;
+
+        /* Patch in the data we found */
+        for (EFI_DEVICE_PATH *node = partition_path; !IsDevicePathEnd(node); node = NextDevicePathNode(node)) {
+                HARDDRIVE_DEVICE_PATH *hd;
+
+                if (DevicePathType(node) != MEDIA_DEVICE_PATH)
+                        continue;
+
+                if (DevicePathSubType(node) != MEDIA_HARDDRIVE_DP)
+                        continue;
+
+                hd = (HARDDRIVE_DEVICE_PATH*) node;
+                hd->PartitionNumber = part_number;
+                hd->PartitionStart = part_start;
+                hd->PartitionSize = part_size;
+                CopyMem(hd->Signature, &part_uuid, sizeof(hd->Signature));
+                hd->MBRType = MBR_TYPE_EFI_PARTITION_TABLE_HEADER;
+                hd->SignatureType = SIGNATURE_TYPE_GUID;
+        }
+
+        err = uefi_call_wrapper(BS->LocateDevicePath, 3, &BlockIoProtocol, &partition_path, &new_device);
+        if (EFI_ERROR(err))
+                return err;
+
+        root_dir = LibOpenRoot(new_device);
+        if (!root_dir)
+                return EFI_NOT_FOUND;
+
+        *ret_device = new_device;
+        *ret_root_dir = root_dir;
+        return EFI_SUCCESS;
+}
diff --git a/src/boot/efi/xbootldr.h b/src/boot/efi/xbootldr.h
new file mode 100644 (file)
index 0000000..4cb370a
--- /dev/null
@@ -0,0 +1,8 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+
+#include <efi.h>
+
+#define XBOOTLDR_GUID \
+        &(const EFI_GUID) { 0xbc13c2ff, 0x59e6, 0x4262, { 0xa3, 0x52, 0xb2, 0x75, 0xfd, 0x6f, 0x71, 0x72 } }
+
+EFI_STATUS xbootldr_open(EFI_HANDLE *device, EFI_HANDLE *ret_device, EFI_FILE **ret_root_dir);
index 862a92a0e2996bee4b1af0cd0ee89358745bfa32..216a9a3c3bdc94a844161a2a9e207c10d679226b 100644 (file)
@@ -354,48 +354,10 @@ static void test_introspect_on_path(void) {
         assert_se(strv_extend(&expected, "/org/freedesktop/LogControl1") >= 0);
         assert_se(strv_extend(&expected, "/org/freedesktop/network1") >= 0);
         assert_se(strv_extend(&expected, "/org/freedesktop/network1/network") >= 0);
-        assert_se(strv_extend(&expected, "/org/freedesktop/network1/network/0") >= 0);
-        assert_se(strv_extend(&expected, "/org/freedesktop/network1/network/0/hoge") >= 0);
-        assert_se(strv_extend(&expected, "/org/freedesktop/network1/network/1") >= 0);
-        assert_se(strv_extend(&expected, "/org/freedesktop/network1/network/1/hoge") >= 0);
-        assert_se(strv_extend(&expected, "/org/freedesktop/network1/network/2") >= 0);
-        assert_se(strv_extend(&expected, "/org/freedesktop/network1/network/2/hoge") >= 0);
-        assert_se(strv_extend(&expected, "/org/freedesktop/network1/network/3") >= 0);
-        assert_se(strv_extend(&expected, "/org/freedesktop/network1/network/3/hoge") >= 0);
-        assert_se(strv_extend(&expected, "/org/freedesktop/network1/network/4") >= 0);
-        assert_se(strv_extend(&expected, "/org/freedesktop/network1/network/4/hoge") >= 0);
-        assert_se(strv_extend(&expected, "/org/freedesktop/network1/network/5") >= 0);
-        assert_se(strv_extend(&expected, "/org/freedesktop/network1/network/5/hoge") >= 0);
-        assert_se(strv_extend(&expected, "/org/freedesktop/network1/network/6") >= 0);
-        assert_se(strv_extend(&expected, "/org/freedesktop/network1/network/6/hoge") >= 0);
-        assert_se(strv_extend(&expected, "/org/freedesktop/network1/network/7") >= 0);
-        assert_se(strv_extend(&expected, "/org/freedesktop/network1/network/7/hoge") >= 0);
-        assert_se(strv_extend(&expected, "/org/freedesktop/network1/network/8") >= 0);
-        assert_se(strv_extend(&expected, "/org/freedesktop/network1/network/8/hoge") >= 0);
-        assert_se(strv_extend(&expected, "/org/freedesktop/network1/network/9") >= 0);
-        assert_se(strv_extend(&expected, "/org/freedesktop/network1/network/9/hoge") >= 0);
-        assert_se(strv_extend(&expected, "/org/freedesktop/network1/network/10") >= 0);
-        assert_se(strv_extend(&expected, "/org/freedesktop/network1/network/10/hoge") >= 0);
-        assert_se(strv_extend(&expected, "/org/freedesktop/network1/network/11") >= 0);
-        assert_se(strv_extend(&expected, "/org/freedesktop/network1/network/11/hoge") >= 0);
-        assert_se(strv_extend(&expected, "/org/freedesktop/network1/network/12") >= 0);
-        assert_se(strv_extend(&expected, "/org/freedesktop/network1/network/12/hoge") >= 0);
-        assert_se(strv_extend(&expected, "/org/freedesktop/network1/network/13") >= 0);
-        assert_se(strv_extend(&expected, "/org/freedesktop/network1/network/13/hoge") >= 0);
-        assert_se(strv_extend(&expected, "/org/freedesktop/network1/network/14") >= 0);
-        assert_se(strv_extend(&expected, "/org/freedesktop/network1/network/14/hoge") >= 0);
-        assert_se(strv_extend(&expected, "/org/freedesktop/network1/network/15") >= 0);
-        assert_se(strv_extend(&expected, "/org/freedesktop/network1/network/15/hoge") >= 0);
-        assert_se(strv_extend(&expected, "/org/freedesktop/network1/network/16") >= 0);
-        assert_se(strv_extend(&expected, "/org/freedesktop/network1/network/16/hoge") >= 0);
-        assert_se(strv_extend(&expected, "/org/freedesktop/network1/network/17") >= 0);
-        assert_se(strv_extend(&expected, "/org/freedesktop/network1/network/17/hoge") >= 0);
-        assert_se(strv_extend(&expected, "/org/freedesktop/network1/network/18") >= 0);
-        assert_se(strv_extend(&expected, "/org/freedesktop/network1/network/18/hoge") >= 0);
-        assert_se(strv_extend(&expected, "/org/freedesktop/network1/network/19") >= 0);
-        assert_se(strv_extend(&expected, "/org/freedesktop/network1/network/19/hoge") >= 0);
-        assert_se(strv_extend(&expected, "/org/freedesktop/network1/network/20") >= 0);
-        assert_se(strv_extend(&expected, "/org/freedesktop/network1/network/20/hoge") >= 0);
+        for (unsigned i = 0; i <= 20; i++) {
+                assert_se(strv_extendf(&expected, "/org/freedesktop/network1/network/%u", i) >= 0);
+                assert_se(strv_extendf(&expected, "/org/freedesktop/network1/network/%u/hoge", i) >= 0);
+        }
 
         strv_sort(expected);
         assert_se(strv_equal(l, expected));
index 11eb352b9b56b6a34fbd050fa35c2af1f618a3be..5a004f82d5225f9e6d36942d21e57b75b02b016d 100644 (file)
@@ -365,7 +365,7 @@ static int open_ioctl_fd(int dev_autofs_fd, const char *where, dev_t devid) {
         assert(where);
 
         l = sizeof(struct autofs_dev_ioctl) + strlen(where) + 1;
-        param = alloca(l);
+        param = alloca_safe(l);
 
         init_autofs_dev_ioctl(param);
         param->size = l;
index 4daa7f76b0cf1fe9ae13269369ff2ac056db4707..4d86e8665f9061ca9c74969fb554dee2329cea85 100644 (file)
@@ -184,7 +184,7 @@ int bpf_devices_cgroup_init(
                             offsetof(struct bpf_cgroup_dev_ctx, minor)),
         };
 
-        _cleanup_(bpf_program_unrefp) BPFProgram *prog = NULL;
+        _cleanup_(bpf_program_freep) BPFProgram *prog = NULL;
         int r;
 
         assert(ret);
@@ -208,7 +208,7 @@ int bpf_devices_cgroup_init(
 }
 
 int bpf_devices_apply_policy(
-                BPFProgram *prog,
+                BPFProgram **prog,
                 CGroupDevicePolicy policy,
                 bool allow_list,
                 const char *cgroup_path,
@@ -219,7 +219,8 @@ int bpf_devices_apply_policy(
 
         /* This will assign *prog_installed if everything goes well. */
 
-        if (!prog)
+        assert(prog);
+        if (!*prog)
                 goto finish;
 
         const bool deny_everything = policy == CGROUP_DEVICE_POLICY_STRICT && !allow_list;
@@ -237,20 +238,20 @@ int bpf_devices_apply_policy(
         };
 
         if (!deny_everything) {
-                r = bpf_program_add_instructions(prog, post_insn, ELEMENTSOF(post_insn));
+                r = bpf_program_add_instructions(*prog, post_insn, ELEMENTSOF(post_insn));
                 if (r < 0)
                         return log_error_errno(r, "Extending device control BPF program failed: %m");
 
                 /* Fixup PASS_JUMP_OFF jump offsets. */
-                for (size_t off = 0; off < prog->n_instructions; off++) {
-                        struct bpf_insn *ins = &prog->instructions[off];
+                for (size_t off = 0; off < (*prog)->n_instructions; off++) {
+                        struct bpf_insn *ins = &((*prog)->instructions[off]);
 
                         if (ins->code == (BPF_JMP | BPF_JA) && ins->off == PASS_JUMP_OFF)
-                                ins->off = prog->n_instructions - off - 1;
+                                ins->off = (*prog)->n_instructions - off - 1;
                 }
         }
 
-        r = bpf_program_add_instructions(prog, exit_insn, ELEMENTSOF(exit_insn));
+        r = bpf_program_add_instructions(*prog, exit_insn, ELEMENTSOF(exit_insn));
         if (r < 0)
                 return log_error_errno(r, "Extending device control BPF program failed: %m");
 
@@ -258,7 +259,7 @@ int bpf_devices_apply_policy(
         if (r < 0)
                 return log_error_errno(r, "Failed to determine cgroup path: %m");
 
-        r = bpf_program_cgroup_attach(prog, BPF_CGROUP_DEVICE, controller_path, BPF_F_ALLOW_MULTI);
+        r = bpf_program_cgroup_attach(*prog, BPF_CGROUP_DEVICE, controller_path, BPF_F_ALLOW_MULTI);
         if (r < 0)
                 return log_error_errno(r, "Attaching device control BPF program to cgroup %s failed: %m",
                                        empty_to_root(cgroup_path));
@@ -266,8 +267,8 @@ int bpf_devices_apply_policy(
  finish:
         /* Unref the old BPF program (which will implicitly detach it) right before attaching the new program. */
         if (prog_installed) {
-                bpf_program_unref(*prog_installed);
-                *prog_installed = bpf_program_ref(prog);
+                bpf_program_free(*prog_installed);
+                *prog_installed = TAKE_PTR(*prog);
         }
         return 0;
 }
@@ -278,7 +279,7 @@ int bpf_devices_supported(void) {
                 BPF_EXIT_INSN()
         };
 
-        _cleanup_(bpf_program_unrefp) BPFProgram *program = NULL;
+        _cleanup_(bpf_program_freep) BPFProgram *program = NULL;
         static int supported = -1;
         int r;
 
index 19b4d392ccc0012d3ded87a960317e364c235d7f..51063640a895c679a2f744ed15de8a7e19f95b62 100644 (file)
@@ -9,7 +9,7 @@ typedef struct BPFProgram BPFProgram;
 
 int bpf_devices_cgroup_init(BPFProgram **ret, CGroupDevicePolicy policy, bool allow_list);
 int bpf_devices_apply_policy(
-                BPFProgram *prog,
+                BPFProgram **prog,
                 CGroupDevicePolicy policy,
                 bool allow_list,
                 const char *cgroup_path,
index d23b43bcb24b9bc6d719718f5b5fe37950d24b57..2c202f1ea60431cbaad2472fa384450751fddfd4 100644 (file)
@@ -192,7 +192,7 @@ static int bpf_firewall_compile_bpf(
                 BPF_MOV64_IMM(BPF_REG_0, 0),
         };
 
-        _cleanup_(bpf_program_unrefp) BPFProgram *p = NULL;
+        _cleanup_(bpf_program_freep) BPFProgram *p = NULL;
         int accounting_map_fd, r;
         bool access_enabled;
 
@@ -555,8 +555,8 @@ int bpf_firewall_compile(Unit *u) {
          * but we reuse the accounting maps. That way the firewall in effect always maps to the actual
          * configuration, but we don't flush out the accounting unnecessarily */
 
-        u->ip_bpf_ingress = bpf_program_unref(u->ip_bpf_ingress);
-        u->ip_bpf_egress = bpf_program_unref(u->ip_bpf_egress);
+        u->ip_bpf_ingress = bpf_program_free(u->ip_bpf_ingress);
+        u->ip_bpf_egress = bpf_program_free(u->ip_bpf_egress);
 
         u->ipv4_allow_map_fd = safe_close(u->ipv4_allow_map_fd);
         u->ipv4_deny_map_fd = safe_close(u->ipv4_deny_map_fd);
@@ -601,7 +601,7 @@ static int load_bpf_progs_from_fs_to_set(Unit *u, char **filter_paths, Set **set
         set_clear(*set);
 
         STRV_FOREACH(bpf_fs_path, filter_paths) {
-                _cleanup_(bpf_program_unrefp) BPFProgram *prog = NULL;
+                _cleanup_(bpf_program_freep) BPFProgram *prog = NULL;
                 int r;
 
                 r = bpf_program_new(BPF_PROG_TYPE_CGROUP_SKB, &prog);
@@ -657,25 +657,20 @@ static int attach_custom_bpf_progs(Unit *u, const char *path, int attach_type, S
         assert(u);
 
         set_clear(*set_installed);
+        r = set_ensure_allocated(set_installed, &bpf_program_hash_ops);
+        if (r < 0)
+                return log_oom();
 
-        SET_FOREACH(prog, *set) {
+        SET_FOREACH_MOVE(prog, *set_installed, *set) {
                 r = bpf_program_cgroup_attach(prog, attach_type, path, BPF_F_ALLOW_MULTI);
                 if (r < 0)
                         return log_unit_error_errno(u, r, "Attaching custom egress BPF program to cgroup %s failed: %m", path);
-
-                /* Remember that these BPF programs are installed now. */
-                r = set_ensure_put(set_installed, &bpf_program_hash_ops, prog);
-                if (r < 0)
-                        return log_unit_error_errno(u, r, "Can't add program to BPF program set: %m");
-
-                bpf_program_ref(prog);
         }
-
         return 0;
 }
 
 int bpf_firewall_install(Unit *u) {
-        _cleanup_(bpf_program_unrefp) BPFProgram *ip_bpf_ingress_uninstall = NULL, *ip_bpf_egress_uninstall = NULL;
+        _cleanup_(bpf_program_freep) BPFProgram *ip_bpf_ingress_uninstall = NULL, *ip_bpf_egress_uninstall = NULL;
         _cleanup_free_ char *path = NULL;
         CGroupContext *cc;
         int r, supported;
@@ -719,8 +714,8 @@ int bpf_firewall_install(Unit *u) {
                 /* If we don't have BPF_F_ALLOW_MULTI then unref the old BPF programs (which will implicitly
                  * detach them) right before attaching the new program, to minimize the time window when we
                  * don't account for IP traffic. */
-                u->ip_bpf_egress_installed = bpf_program_unref(u->ip_bpf_egress_installed);
-                u->ip_bpf_ingress_installed = bpf_program_unref(u->ip_bpf_ingress_installed);
+                u->ip_bpf_egress_installed = bpf_program_free(u->ip_bpf_egress_installed);
+                u->ip_bpf_ingress_installed = bpf_program_free(u->ip_bpf_ingress_installed);
         }
 
         if (u->ip_bpf_egress) {
@@ -729,7 +724,7 @@ int bpf_firewall_install(Unit *u) {
                         return log_unit_error_errno(u, r, "Attaching egress BPF program to cgroup %s failed: %m", path);
 
                 /* Remember that this BPF program is installed now. */
-                u->ip_bpf_egress_installed = bpf_program_ref(u->ip_bpf_egress);
+                u->ip_bpf_egress_installed = TAKE_PTR(u->ip_bpf_egress);
         }
 
         if (u->ip_bpf_ingress) {
@@ -737,12 +732,12 @@ int bpf_firewall_install(Unit *u) {
                 if (r < 0)
                         return log_unit_error_errno(u, r, "Attaching ingress BPF program to cgroup %s failed: %m", path);
 
-                u->ip_bpf_ingress_installed = bpf_program_ref(u->ip_bpf_ingress);
+                u->ip_bpf_ingress_installed = TAKE_PTR(u->ip_bpf_ingress);
         }
 
         /* And now, definitely get rid of the old programs, and detach them */
-        ip_bpf_egress_uninstall = bpf_program_unref(ip_bpf_egress_uninstall);
-        ip_bpf_ingress_uninstall = bpf_program_unref(ip_bpf_ingress_uninstall);
+        ip_bpf_egress_uninstall = bpf_program_free(ip_bpf_egress_uninstall);
+        ip_bpf_ingress_uninstall = bpf_program_free(ip_bpf_ingress_uninstall);
 
         r = attach_custom_bpf_progs(u, path, BPF_CGROUP_INET_EGRESS, &u->ip_bpf_custom_egress, &u->ip_bpf_custom_egress_installed);
         if (r < 0)
@@ -806,7 +801,7 @@ int bpf_firewall_supported(void) {
                 BPF_EXIT_INSN()
         };
 
-        _cleanup_(bpf_program_unrefp) BPFProgram *program = NULL;
+        _cleanup_(bpf_program_freep) BPFProgram *program = NULL;
         static int supported = -1;
         union bpf_attr attr;
         int r;
@@ -936,10 +931,10 @@ void bpf_firewall_close(Unit *u) {
         u->ipv4_deny_map_fd = safe_close(u->ipv4_deny_map_fd);
         u->ipv6_deny_map_fd = safe_close(u->ipv6_deny_map_fd);
 
-        u->ip_bpf_ingress = bpf_program_unref(u->ip_bpf_ingress);
-        u->ip_bpf_ingress_installed = bpf_program_unref(u->ip_bpf_ingress_installed);
-        u->ip_bpf_egress = bpf_program_unref(u->ip_bpf_egress);
-        u->ip_bpf_egress_installed = bpf_program_unref(u->ip_bpf_egress_installed);
+        u->ip_bpf_ingress = bpf_program_free(u->ip_bpf_ingress);
+        u->ip_bpf_ingress_installed = bpf_program_free(u->ip_bpf_ingress_installed);
+        u->ip_bpf_egress = bpf_program_free(u->ip_bpf_egress);
+        u->ip_bpf_egress_installed = bpf_program_free(u->ip_bpf_egress_installed);
 
         u->ip_bpf_custom_ingress = set_free(u->ip_bpf_custom_ingress);
         u->ip_bpf_custom_egress = set_free(u->ip_bpf_custom_egress);
index 27e5517519be64dd326ee851f542fbb4987745a2..6b93b9785fb5e1344ab4e297c55a3fd07ac67529 100644 (file)
@@ -49,7 +49,7 @@ static void bpf_foreign_key_hash_func(const BPFForeignKey *p, struct siphash *h)
 
 DEFINE_PRIVATE_HASH_OPS_FULL(bpf_foreign_by_key_hash_ops,
                 BPFForeignKey, bpf_foreign_key_hash_func, bpf_foreign_key_compare_func, free,
-                BPFProgram, bpf_program_unref);
+                BPFProgram, bpf_program_free);
 
 static int attach_programs(Unit *u, const char *path, Hashmap* foreign_by_key, uint32_t attach_flags) {
         const BPFForeignKey *key;
@@ -76,7 +76,7 @@ static int bpf_foreign_prepare(
                 Unit *u,
                 enum bpf_attach_type attach_type,
                 const char *bpffs_path) {
-        _cleanup_(bpf_program_unrefp) BPFProgram *prog = NULL;
+        _cleanup_(bpf_program_freep) BPFProgram *prog = NULL;
         _cleanup_free_ BPFForeignKey *key = NULL;
         uint32_t prog_id;
         int r;
index 7a21f5276e4877440496b9b15c8b38748fb8df56..c92cccae260e337d449bb62e12e7395f29512758 100644 (file)
@@ -1,4 +1,4 @@
-# SPDX-License-Identifier: LGPL-2.1+
+# SPDX-License-Identifier: LGPL-2.1-or-later
 
 if conf.get('BPF_FRAMEWORK') == 1
         restrict_fs_skel_h = custom_target(
index 2b15310191b5ff213c6a9e50601cb3ae0c1bb4dc..931b31e2e1874db67a050759d9f130405058b675 100644 (file)
@@ -1170,7 +1170,7 @@ static void cgroup_apply_restrict_network_interfaces(Unit *u) {
 }
 
 static int cgroup_apply_devices(Unit *u) {
-        _cleanup_(bpf_program_unrefp) BPFProgram *prog = NULL;
+        _cleanup_(bpf_program_freep) BPFProgram *prog = NULL;
         const char *path;
         CGroupContext *c;
         CGroupDeviceAllow *a;
@@ -1244,7 +1244,7 @@ static int cgroup_apply_devices(Unit *u) {
                 policy = CGROUP_DEVICE_POLICY_STRICT;
         }
 
-        r = bpf_devices_apply_policy(prog, policy, any, path, &u->bpf_device_control_installed);
+        r = bpf_devices_apply_policy(&prog, policy, any, path, &u->bpf_device_control_installed);
         if (r < 0) {
                 static bool warned = false;
 
@@ -2767,7 +2767,7 @@ void unit_prune_cgroup(Unit *u) {
         u->cgroup_realized_mask = 0;
         u->cgroup_enabled_mask = 0;
 
-        u->bpf_device_control_installed = bpf_program_unref(u->bpf_device_control_installed);
+        u->bpf_device_control_installed = bpf_program_free(u->bpf_device_control_installed);
 }
 
 int unit_search_main_pid(Unit *u, pid_t *ret) {
@@ -3437,7 +3437,7 @@ Unit* manager_get_unit_by_cgroup(Manager *m, const char *cgroup) {
         if (u)
                 return u;
 
-        p = strdupa(cgroup);
+        p = strdupa_safe(cgroup);
         for (;;) {
                 char *e;
 
index 44f9ee57bdbdbc7dd47f4cf06684a0cbd0fdc5ac..1c82c7d90db81cbb45251bb36596213eb3732dca 100644 (file)
@@ -3462,7 +3462,7 @@ int bus_exec_context_set_transient_property(
                         if (soft) {
                                 const char *n;
 
-                                n = strndupa(suffix, soft - suffix);
+                                n = strndupa_safe(suffix, soft - suffix);
                                 ri = rlimit_from_string(n);
                                 if (ri >= 0)
                                         name = strjoina("Limit", n);
index f0e75d5bc279af1107a7b7199f9e9a1f8e6f0fe6..32a2ec0ff901992104173fea502f977cccbef289 100644 (file)
@@ -117,7 +117,7 @@ int bus_set_transient_usec_internal(
                 else
                         *p = v;
 
-                char *n = strndupa(name, strlen(name) - 4);
+                char *n = strndupa_safe(name, strlen(name) - 4);
                 unit_write_settingf(u, flags, name, "%sSec=%s", n, FORMAT_TIMESPAN(v, USEC_PER_MSEC));
         }
 
index 6397bab315a6deb3bcec5725e72644b2a9132862..9d100889018da4e7311607ab6ea46e9fad2ea88c 100644 (file)
@@ -4136,13 +4136,17 @@ static int exec_child(
                 }
         }
 
-        if (context->utmp_id)
+        if (context->utmp_id) {
+                const char *line = context->tty_path ?
+                        (path_startswith(context->tty_path, "/dev/") ?: context->tty_path) :
+                        NULL;
                 utmp_put_init_process(context->utmp_id, getpid_cached(), getsid(0),
-                                      context->tty_path,
+                                      line,
                                       context->utmp_mode == EXEC_UTMP_INIT  ? INIT_PROCESS :
                                       context->utmp_mode == EXEC_UTMP_LOGIN ? LOGIN_PROCESS :
                                       USER_PROCESS,
                                       username);
+        }
 
         if (uid_is_valid(uid)) {
                 r = chown_terminal(STDIN_FILENO, uid);
@@ -6524,7 +6528,7 @@ int exec_runtime_deserialize_one(Manager *m, const char *value, FDSet *fds) {
         assert(fds);
 
         n = strcspn(v, " ");
-        id = strndupa(v, n);
+        id = strndupa_safe(v, n);
         if (v[n] != ' ')
                 goto finalize;
         p = v + n + 1;
@@ -6556,7 +6560,7 @@ int exec_runtime_deserialize_one(Manager *m, const char *value, FDSet *fds) {
                 char *buf;
 
                 n = strcspn(v, " ");
-                buf = strndupa(v, n);
+                buf = strndupa_safe(v, n);
 
                 r = safe_atoi(buf, &netns_fdpair[0]);
                 if (r < 0)
@@ -6575,7 +6579,7 @@ int exec_runtime_deserialize_one(Manager *m, const char *value, FDSet *fds) {
                 char *buf;
 
                 n = strcspn(v, " ");
-                buf = strndupa(v, n);
+                buf = strndupa_safe(v, n);
 
                 r = safe_atoi(buf, &netns_fdpair[1]);
                 if (r < 0)
@@ -6594,7 +6598,7 @@ int exec_runtime_deserialize_one(Manager *m, const char *value, FDSet *fds) {
                 char *buf;
 
                 n = strcspn(v, " ");
-                buf = strndupa(v, n);
+                buf = strndupa_safe(v, n);
 
                 r = safe_atoi(buf, &ipcns_fdpair[0]);
                 if (r < 0)
@@ -6613,7 +6617,7 @@ int exec_runtime_deserialize_one(Manager *m, const char *value, FDSet *fds) {
                 char *buf;
 
                 n = strcspn(v, " ");
-                buf = strndupa(v, n);
+                buf = strndupa_safe(v, n);
 
                 r = safe_atoi(buf, &ipcns_fdpair[1]);
                 if (r < 0)
index 10fe579aeb36ce574e55d97d16b951dadebcfdc9..18d9bb377c7a469494d8aa9623d60a72615b8da9 100644 (file)
@@ -6334,3 +6334,34 @@ int config_parse_swap_priority(
         s->parameters_fragment.priority_set = true;
         return 0;
 }
+
+int config_parse_watchdog_sec(
+                const char *unit,
+                const char *filename,
+                unsigned line,
+                const char *section,
+                unsigned section_line,
+                const char *lvalue,
+                int ltype,
+                const char *rvalue,
+                void *data,
+                void *userdata) {
+
+        usec_t *usec = data;
+
+        assert(filename);
+        assert(lvalue);
+        assert(rvalue);
+
+        /* This is called for {Runtime,Reboot,KExec}WatchdogSec= where "default" maps to
+         * USEC_INFINITY internally. */
+
+        if (streq(rvalue, "default"))
+                *usec = USEC_INFINITY;
+        else if (streq(rvalue, "off"))
+                *usec = 0;
+        else
+                return config_parse_sec(unit, filename, line, section, section_line, lvalue, ltype, rvalue, data, userdata);
+
+        return 0;
+}
index 9173f30addd7af32699a99a56fe87b2265c5d608..96ccb426e6457a5baf0954f6d74c3f9204a00c99 100644 (file)
@@ -143,6 +143,7 @@ CONFIG_PARSER_PROTOTYPE(config_parse_extension_images);
 CONFIG_PARSER_PROTOTYPE(config_parse_bpf_foreign_program);
 CONFIG_PARSER_PROTOTYPE(config_parse_cgroup_socket_bind);
 CONFIG_PARSER_PROTOTYPE(config_parse_restrict_network_interfaces);
+CONFIG_PARSER_PROTOTYPE(config_parse_watchdog_sec);
 
 /* gperf prototypes */
 const struct ConfigPerfItem* load_fragment_gperf_lookup(const char *key, GPERF_LEN_TYPE length);
index 62f39c7378f418c4c43762762951252c145fe251..6e01398523c47a7516346e20308b4230e5a65164 100644 (file)
@@ -537,6 +537,25 @@ static int parse_proc_cmdline_item(const char *key, const char *value, void *dat
 
                 (void) parse_path_argument(value, false, &arg_watchdog_device);
 
+        } else if (proc_cmdline_key_streq(key, "systemd.watchdog_sec")) {
+
+                if (proc_cmdline_value_missing(key, value))
+                        return 0;
+
+                if (streq(value, "default"))
+                        arg_runtime_watchdog = USEC_INFINITY;
+                else if (streq(value, "off"))
+                        arg_runtime_watchdog = 0;
+                else {
+                        r = parse_sec(value, &arg_runtime_watchdog);
+                        if (r < 0) {
+                                log_warning_errno(r, "Failed to parse systemd.watchdog_sec= argument '%s', ignoring: %m", value);
+                                return 0;
+                        }
+                }
+
+                arg_kexec_watchdog = arg_reboot_watchdog = arg_runtime_watchdog;
+
         } else if (proc_cmdline_key_streq(key, "systemd.clock_usec")) {
 
                 if (proc_cmdline_value_missing(key, value))
@@ -688,10 +707,10 @@ static int parse_config_file(void) {
                 { "Manager", "NUMAPolicy",                   config_parse_numa_policy,           0, &arg_numa_policy.type                  },
                 { "Manager", "NUMAMask",                     config_parse_numa_mask,             0, &arg_numa_policy                       },
                 { "Manager", "JoinControllers",              config_parse_warn_compat,           DISABLED_CONFIGURATION, NULL              },
-                { "Manager", "RuntimeWatchdogSec",           config_parse_sec,                   0, &arg_runtime_watchdog                  },
-                { "Manager", "RebootWatchdogSec",            config_parse_sec,                   0, &arg_reboot_watchdog                   },
-                { "Manager", "ShutdownWatchdogSec",          config_parse_sec,                   0, &arg_reboot_watchdog                   }, /* obsolete alias */
-                { "Manager", "KExecWatchdogSec",             config_parse_sec,                   0, &arg_kexec_watchdog                    },
+                { "Manager", "RuntimeWatchdogSec",           config_parse_watchdog_sec,          0, &arg_runtime_watchdog                  },
+                { "Manager", "RebootWatchdogSec",            config_parse_watchdog_sec,          0, &arg_reboot_watchdog                   },
+                { "Manager", "ShutdownWatchdogSec",          config_parse_watchdog_sec,          0, &arg_reboot_watchdog                   }, /* obsolete alias */
+                { "Manager", "KExecWatchdogSec",             config_parse_watchdog_sec,          0, &arg_kexec_watchdog                    },
                 { "Manager", "WatchdogDevice",               config_parse_path,                  0, &arg_watchdog_device                   },
                 { "Manager", "CapabilityBoundingSet",        config_parse_capability_set,        0, &arg_capability_bounding_set           },
                 { "Manager", "NoNewPrivileges",              config_parse_bool,                  0, &arg_no_new_privs                      },
@@ -1523,9 +1542,9 @@ static int become_shutdown(
         };
 
         _cleanup_strv_free_ char **env_block = NULL;
+        usec_t watchdog_timer = 0;
         size_t pos = 7;
         int r;
-        usec_t watchdog_timer = 0;
 
         assert(shutdown_verb);
         assert(!command_line[pos]);
@@ -1574,19 +1593,16 @@ static int become_shutdown(
         else if (streq(shutdown_verb, "kexec"))
                 watchdog_timer = arg_kexec_watchdog;
 
-        if (timestamp_is_set(watchdog_timer)) {
-                /* If we reboot or kexec let's set the shutdown watchdog and tell the shutdown binary to
-                 * repeatedly ping it */
-                r = watchdog_setup(watchdog_timer);
-                watchdog_close(r < 0);
+        /* If we reboot or kexec let's set the shutdown watchdog and tell the
+         * shutdown binary to repeatedly ping it */
+        r = watchdog_setup(watchdog_timer);
+        watchdog_close(r < 0);
 
-                /* Tell the binary how often to ping, ignore failure */
-                (void) strv_extendf(&env_block, "WATCHDOG_USEC="USEC_FMT, watchdog_timer);
+        /* Tell the binary how often to ping, ignore failure */
+        (void) strv_extendf(&env_block, "WATCHDOG_USEC="USEC_FMT, watchdog_timer);
 
-                if (arg_watchdog_device)
-                        (void) strv_extendf(&env_block, "WATCHDOG_DEVICE=%s", arg_watchdog_device);
-        } else
-                watchdog_close(true);
+        if (arg_watchdog_device)
+                (void) strv_extendf(&env_block, "WATCHDOG_DEVICE=%s", arg_watchdog_device);
 
         /* Avoid the creation of new processes forked by the kernel; at this
          * point, we will not listen to the signals anyway */
index 6bcb6bd15359a1c9955ab8de9deed49c88341883..167fa1a34aa61a3771513ebf034cc98ae7cde888 100644 (file)
@@ -3215,12 +3215,8 @@ void manager_set_watchdog(Manager *m, WatchdogType t, usec_t timeout) {
                 return;
 
         if (t == WATCHDOG_RUNTIME)
-                if (!timestamp_is_set(m->watchdog_overridden[WATCHDOG_RUNTIME])) {
-                        if (timestamp_is_set(timeout))
-                                (void) watchdog_setup(timeout);
-                        else
-                                watchdog_close(true);
-                }
+                if (!timestamp_is_set(m->watchdog_overridden[WATCHDOG_RUNTIME]))
+                        (void) watchdog_setup(timeout);
 
         m->watchdog[t] = timeout;
 }
@@ -3238,10 +3234,7 @@ int manager_override_watchdog(Manager *m, WatchdogType t, usec_t timeout) {
         if (t == WATCHDOG_RUNTIME) {
                 usec_t usec = timestamp_is_set(timeout) ? timeout : m->watchdog[t];
 
-                if (timestamp_is_set(usec))
-                        (void) watchdog_setup(usec);
-                else
-                        watchdog_close(true);
+                (void) watchdog_setup(usec);
         }
 
         m->watchdog_overridden[t] = timeout;
index 984e324d74aa7103d0f9853f11ce157e92930506..513a4fb00e7dc1d12349dd01e0af21ae7d2955b5 100644 (file)
@@ -126,7 +126,7 @@ _printf_(2, 3) static int log_callback(int type, const char *fmt, ...) {
 
         DISABLE_WARNING_FORMAT_NONLITERAL;
         log_internalv(LOG_AUTH | callback_type_to_priority(type),
-                      0, PROJECT_FILE, __LINE__, __FUNCTION__,
+                      0, PROJECT_FILE, __LINE__, __func__,
                       fmt2, ap);
         REENABLE_WARNING;
         va_end(ap);
index e88280bd0a7b52e4c0d7dfd0b6e257d2bb77a28c..96fb64d2c1e4f9b2547b55789f7c9760234845c1 100644 (file)
@@ -29,9 +29,9 @@
 #CPUAffinity=
 #NUMAPolicy=default
 #NUMAMask=
-#RuntimeWatchdogSec=0
+#RuntimeWatchdogSec=off
 #RebootWatchdogSec=10min
-#KExecWatchdogSec=0
+#KExecWatchdogSec=off
 #WatchdogDevice=
 #CapabilityBoundingSet=
 #NoNewPrivileges=no
index 9e1664ff53af5215e5f52930313d1d44e73d5799..3458d7017bd5550a28a86b41e048c45e15ebe7c6 100644 (file)
@@ -171,6 +171,7 @@ int unit_serialize(Unit *u, FILE *f, FDSet *fds, bool switching_root) {
 
         (void) bpf_program_serialize_attachment(f, fds, "ip-bpf-ingress-installed", u->ip_bpf_ingress_installed);
         (void) bpf_program_serialize_attachment(f, fds, "ip-bpf-egress-installed", u->ip_bpf_egress_installed);
+        (void) bpf_program_serialize_attachment(f, fds, "bpf-device-control-installed", u->bpf_device_control_installed);
         (void) bpf_program_serialize_attachment_set(f, fds, "ip-bpf-custom-ingress-installed", u->ip_bpf_custom_ingress_installed);
         (void) bpf_program_serialize_attachment_set(f, fds, "ip-bpf-custom-egress-installed", u->ip_bpf_custom_egress_installed);
 
@@ -408,6 +409,9 @@ int unit_deserialize(Unit *u, FILE *f, FDSet *fds) {
                 } else if (streq(l, "ip-bpf-egress-installed")) {
                          (void) bpf_program_deserialize_attachment(v, fds, &u->ip_bpf_egress_installed);
                          continue;
+                } else if (streq(l, "bpf-device-control-installed")) {
+                         (void) bpf_program_deserialize_attachment(v, fds, &u->bpf_device_control_installed);
+                         continue;
 
                 } else if (streq(l, "ip-bpf-custom-ingress-installed")) {
                          (void) bpf_program_deserialize_attachment_set(v, fds, &u->ip_bpf_custom_ingress_installed);
index 05341a64f569636b510f0b2d598cea6c598e2c6f..d8b4179239a244b8b99b1364ef190a15858ad209 100644 (file)
@@ -770,7 +770,7 @@ Unit* unit_free(Unit *u) {
 
         hashmap_free(u->bpf_foreign_by_key);
 
-        bpf_program_unref(u->bpf_device_control_installed);
+        bpf_program_free(u->bpf_device_control_installed);
 
 #if BPF_FRAMEWORK
         bpf_link_free(u->restrict_ifaces_ingress_bpf_link);
index 95c3fca66186e5f5a1852e6ba59cbcfc9bc2f8c4..0c08ab21dc44b65874822fd679bacf7ae0565b4c 100644 (file)
@@ -61,7 +61,7 @@ static int uid_from_file_name(const char *filename, uid_t *uid) {
         if (!e)
                 return -EINVAL;
 
-        u = strndupa(p, e-p);
+        u = strndupa_safe(p, e - p);
         return parse_uid(u, uid);
 }
 
index 2eaa56a4fd957cb4623ddf2b76c89449d11a8a67..3f6537faeecc400da5de989b025b8d98695e6526 100644 (file)
@@ -563,6 +563,8 @@ static int print_info(FILE *file, sd_journal *j, bool need_space) {
         assert(file);
         assert(j);
 
+        (void) sd_journal_set_data_threshold(j, 0);
+
         SD_JOURNAL_FOREACH_DATA(j, d, l) {
                 RETRIEVE(d, l, "MESSAGE_ID", mid);
                 RETRIEVE(d, l, "COREDUMP_PID", pid);
index 3a870016d31202aaaf948069b10898c02d125c75..35d5dbe007568bde3b75ad93d7cece01d91b2d4e 100644 (file)
@@ -32,6 +32,7 @@ int acquire_fido2_key(
 
         _cleanup_strv_free_erase_ char **pins = NULL;
         _cleanup_free_ void *loaded_salt = NULL;
+        bool device_exists = false;
         const char *salt;
         size_t salt_size;
         char *e;
@@ -89,13 +90,29 @@ int acquire_fido2_key(
                                     -ENOANO,   /* needs pin */
                                     -ENOLCK))  /* pin incorrect */
                                 return r;
-                }
 
-                pins = strv_free_erase(pins);
+                        device_exists = true; /* that a PIN is needed/wasn't correct means that we managed to
+                                               * talk to a device */
+                }
 
                 if (headless)
                         return log_error_errno(SYNTHETIC_ERRNO(ENOPKG), "PIN querying disabled via 'headless' option. Use the '$PIN' environment variable.");
 
+                if (!device_exists) {
+                        /* Before we inquire for the PIN we'll need, if we never talked to the device, check
+                         * if the device actually is plugged in. Otherwise we'll ask for the PIN already when
+                         * the device is not plugged in, which is confusing. */
+
+                        r = fido2_have_device(device);
+                        if (r < 0)
+                                return r;
+                        if (r == 0) /* no device found, return EAGAIN so that caller will wait/watch udev */
+                                return -EAGAIN;
+
+                        device_exists = true;  /* now we know for sure, a device exists, no need to ask again */
+                }
+
+                pins = strv_free_erase(pins);
                 r = ask_password_auto("Please enter security token PIN:", "drive-harddisk", NULL, "fido2-pin", "cryptsetup.fido2-pin", until, ask_password_flags, &pins);
                 if (r < 0)
                         return log_error_errno(r, "Failed to ask for user password: %m");
index 2c5b0e8f7df0c03f2734f9ce6b199ae5854a6fb9..250a8314f65db56d929f5cdefd6652254f0b26cc 100644 (file)
@@ -18,6 +18,7 @@
 #include "cryptsetup-util.h"
 #include "device-util.h"
 #include "efi-loader.h"
+#include "env-util.h"
 #include "escape.h"
 #include "fileio.h"
 #include "fs-util.h"
@@ -82,6 +83,7 @@ static char *arg_tpm2_device = NULL;
 static bool arg_tpm2_device_auto = false;
 static uint32_t arg_tpm2_pcr_mask = UINT32_MAX;
 static bool arg_headless = false;
+static usec_t arg_token_timeout_usec = 30*USEC_PER_SEC;
 
 STATIC_DESTRUCTOR_REGISTER(arg_cipher, freep);
 STATIC_DESTRUCTOR_REGISTER(arg_hash, freep);
@@ -409,7 +411,15 @@ static int parse_one_option(const char *option) {
         } else if (streq(option, "headless"))
                 arg_headless = true;
 
-        else if (!streq(option, "x-initrd.attach"))
+        else if ((val = startswith(option, "token-timeout="))) {
+
+                r = parse_sec_fix_0(val, &arg_token_timeout_usec);
+                if (r < 0) {
+                        log_error_errno(r, "Failed to parse %s, ignoring: %m", option);
+                        return 0;
+                }
+
+        } else if (!streq(option, "x-initrd.attach"))
                 log_warning("Encountered unknown /etc/crypttab option '%s', ignoring.", option);
 
         return 0;
@@ -710,11 +720,25 @@ static char *make_bindname(const char *volume) {
         return s;
 }
 
-static int make_security_device_monitor(sd_event *event, sd_device_monitor **ret) {
+static int make_security_device_monitor(
+                sd_event **ret_event,
+                sd_device_monitor **ret_monitor) {
         _cleanup_(sd_device_monitor_unrefp) sd_device_monitor *monitor = NULL;
+        _cleanup_(sd_event_unrefp) sd_event *event = NULL;
         int r;
 
-        assert(ret);
+        assert(ret_event);
+        assert(ret_monitor);
+
+        /* Waits for a device with "security-device" tag to show up in udev */
+
+        r = sd_event_default(&event);
+        if (r < 0)
+                return log_error_errno(r, "Failed to allocate event loop: %m");
+
+        r = sd_event_add_time_relative(event, NULL, CLOCK_MONOTONIC, arg_token_timeout_usec, USEC_PER_SEC, NULL, INT_TO_PTR(-ETIMEDOUT));
+        if (r < 0)
+                return log_error_errno(r, "Failed to install timeout event source: %m");
 
         r = sd_device_monitor_new(&monitor);
         if (r < 0)
@@ -732,13 +756,61 @@ static int make_security_device_monitor(sd_event *event, sd_device_monitor **ret
         if (r < 0)
                 return log_error_errno(r, "Failed to start device monitor: %m");
 
-        *ret = TAKE_PTR(monitor);
+        *ret_event = TAKE_PTR(event);
+        *ret_monitor = TAKE_PTR(monitor);
         return 0;
 }
 
+static int run_security_device_monitor(
+                sd_event *event,
+                sd_device_monitor *monitor) {
+        bool processed = false;
+        int r;
+
+        assert(event);
+        assert(monitor);
+
+        /* Runs the event loop for the device monitor until either something happens, or the time-out is
+         * hit. */
+
+        for (;;) {
+                int x;
+
+                r = sd_event_get_exit_code(event, &x);
+                if (r < 0) {
+                        if (r != -ENODATA)
+                                return log_error_errno(r, "Failed to query exit code from event loop: %m");
+
+                        /* On ENODATA we aren't told to exit yet. */
+                } else {
+                        assert(x == -ETIMEDOUT);
+                        return log_notice_errno(SYNTHETIC_ERRNO(EAGAIN),
+                                                "Timed out waiting for security device, aborting security device based authentication attempt.");
+                }
+
+                /* Wait for one event, and then eat all subsequent events until there are no further ones */
+                r = sd_event_run(event, processed ? 0 : UINT64_MAX);
+                if (r < 0)
+                        return log_error_errno(r, "Failed to run event loop: %m");
+                if (r == 0) /* no events queued anymore */
+                        return 0;
+
+                processed = true;
+        }
+}
+
 static bool libcryptsetup_plugins_support(void) {
 #if HAVE_LIBCRYPTSETUP_PLUGINS
-        return crypt_token_external_path() != NULL;
+        int r;
+
+        /* Permit a way to disable libcryptsetup token module support, for debugging purposes. */
+        r = getenv_bool("SYSTEMD_CRYPTSETUP_USE_TOKEN_MODULE");
+        if (r < 0 && r != -ENXIO)
+                log_debug_errno(r, "Failed to parse $SYSTEMD_CRYPTSETUP_USE_TOKEN_MODULE env var: %m");
+        if (r == 0)
+                return false;
+
+        return crypt_token_external_path();
 #else
         return false;
 #endif
@@ -776,11 +848,11 @@ static int attach_luks2_by_fido2(
                 void *usrptr,
                 uint32_t activation_flags) {
 
-        int r = -EOPNOTSUPP;
 #if HAVE_LIBCRYPTSETUP_PLUGINS
-        char **p;
-        _cleanup_strv_free_erase_ char **pins = NULL;
         AskPasswordFlags flags = ASK_PASSWORD_PUSH_CACHE | ASK_PASSWORD_ACCEPT_CACHED;
+        _cleanup_strv_free_erase_ char **pins = NULL;
+        char **p;
+        int r;
 
         r = crypt_activate_by_token_pin(cd, name, "systemd-fido2", CRYPT_ANY_TOKEN, NULL, 0, usrptr, activation_flags);
         if (r > 0) /* returns unlocked keyslot id on success */
@@ -803,20 +875,6 @@ static int attach_luks2_by_fido2(
         if (headless)
                 return log_error_errno(SYNTHETIC_ERRNO(ENOPKG), "PIN querying disabled via 'headless' option. Use the '$PIN' environment variable.");
 
-        pins = strv_free_erase(pins);
-        r = ask_password_auto("Please enter security token PIN:", "drive-harddisk", NULL, "fido2-pin", "cryptsetup.fido2-pin", until, flags, &pins);
-        if (r < 0)
-                return r;
-
-        STRV_FOREACH(p, pins) {
-                r = crypt_activate_by_token_pin(cd, name, "systemd-fido2", CRYPT_ANY_TOKEN, *p, strlen(*p), usrptr, activation_flags);
-                if (r > 0) /* returns unlocked keyslot id on success */
-                        r = 0;
-                if (r != -ENOANO) /* needs pin or pin is wrong */
-                        return r;
-        }
-
-        flags &= ~ASK_PASSWORD_ACCEPT_CACHED;
         for (;;) {
                 pins = strv_free_erase(pins);
                 r = ask_password_auto("Please enter security token PIN:", "drive-harddisk", NULL, "fido2-pin", "cryptsetup.fido2-pin", until, flags, &pins);
@@ -830,9 +888,13 @@ static int attach_luks2_by_fido2(
                         if (r != -ENOANO) /* needs pin or pin is wrong */
                                 return r;
                 }
+
+                flags &= ~ASK_PASSWORD_ACCEPT_CACHED;
         }
-#endif
         return r;
+#else
+        return -EOPNOTSUPP;
+#endif
 }
 
 static int attach_luks_or_plain_or_bitlk_by_fido2(
@@ -908,8 +970,6 @@ static int attach_luks_or_plain_or_bitlk_by_fido2(
                 return log_oom();
 
         for (;;) {
-                bool processed = false;
-
                 if (use_libcryptsetup_plugin && !arg_fido2_cid) {
                         r = attach_luks2_by_fido2(cd, name, until, arg_headless, arg_fido2_device, flags);
                         if (IN_SET(r, -ENOTUNIQ, -ENXIO, -ENOENT))
@@ -943,11 +1003,7 @@ static int attach_luks_or_plain_or_bitlk_by_fido2(
 
                         assert(!event);
 
-                        r = sd_event_default(&event);
-                        if (r < 0)
-                                return log_error_errno(r, "Failed to allocate event loop: %m");
-
-                        r = make_security_device_monitor(event, &monitor);
+                        r = make_security_device_monitor(&event, &monitor);
                         if (r < 0)
                                 return r;
 
@@ -958,17 +1014,9 @@ static int attach_luks_or_plain_or_bitlk_by_fido2(
                         continue;
                 }
 
-                for (;;) {
-                        /* Wait for one event, and then eat all subsequent events until there are no
-                         * further ones */
-                        r = sd_event_run(event, processed ? 0 : UINT64_MAX);
-                        if (r < 0)
-                                return log_error_errno(r, "Failed to run event loop: %m");
-                        if (r == 0)
-                                break;
-
-                        processed = true;
-                }
+                r = run_security_device_monitor(event, monitor);
+                if (r < 0)
+                        return r;
 
                 log_debug("Got one or more potentially relevant udev events, rescanning FIDO2...");
         }
@@ -1004,9 +1052,10 @@ static int attach_luks2_by_pkcs11(
                 bool headless,
                 uint32_t flags) {
 
-        int r = -EOPNOTSUPP;
 #if HAVE_LIBCRYPTSETUP_PLUGINS
-        if (!crypt_get_type(cd) || strcmp(crypt_get_type(cd), CRYPT_LUKS2))
+        int r;
+
+        if (!streq_ptr(crypt_get_type(cd), CRYPT_LUKS2))
                 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Automatic PKCS#11 metadata requires LUKS2 device.");
 
         systemd_pkcs11_plugin_params params = {
@@ -1018,8 +1067,11 @@ static int attach_luks2_by_pkcs11(
         r = crypt_activate_by_token_pin(cd, name, "systemd-pkcs11", CRYPT_ANY_TOKEN, NULL, 0, &params, flags);
         if (r > 0) /* returns unlocked keyslot id on success */
                 r = 0;
-#endif
+
         return r;
+#else
+        return -EOPNOTSUPP;
+#endif
 }
 
 static int attach_luks_or_plain_or_bitlk_by_pkcs11(
@@ -1071,8 +1123,6 @@ static int attach_luks_or_plain_or_bitlk_by_pkcs11(
                 return log_oom();
 
         for (;;) {
-                bool processed = false;
-
                 if (use_libcryptsetup_plugin && arg_pkcs11_uri_auto)
                         r = attach_luks2_by_pkcs11(cd, name, friendly, until, arg_headless, flags);
                 else {
@@ -1098,11 +1148,7 @@ static int attach_luks_or_plain_or_bitlk_by_pkcs11(
 
                         assert(!event);
 
-                        r = sd_event_default(&event);
-                        if (r < 0)
-                                return log_error_errno(r, "Failed to allocate event loop: %m");
-
-                        r = make_security_device_monitor(event, &monitor);
+                        r = make_security_device_monitor(&event, &monitor);
                         if (r < 0)
                                 return r;
 
@@ -1114,17 +1160,9 @@ static int attach_luks_or_plain_or_bitlk_by_pkcs11(
                         continue;
                 }
 
-                for (;;) {
-                        /* Wait for one event, and then eat all subsequent events until there are no
-                         * further ones */
-                        r = sd_event_run(event, processed ? 0 : UINT64_MAX);
-                        if (r < 0)
-                                return log_error_errno(r, "Failed to run event loop: %m");
-                        if (r == 0)
-                                break;
-
-                        processed = true;
-                }
+                r = run_security_device_monitor(event, monitor);
+                if (r < 0)
+                        return r;
 
                 log_debug("Got one or more potentially relevant udev events, rescanning PKCS#11...");
         }
@@ -1159,11 +1197,24 @@ static int attach_luks_or_plain_or_bitlk_by_pkcs11(
         return 0;
 }
 
-static int make_tpm2_device_monitor(sd_event *event, sd_device_monitor **ret) {
+static int make_tpm2_device_monitor(
+                sd_event **ret_event,
+                sd_device_monitor **ret_monitor) {
+
         _cleanup_(sd_device_monitor_unrefp) sd_device_monitor *monitor = NULL;
+        _cleanup_(sd_event_unrefp) sd_event *event = NULL;
         int r;
 
-        assert(ret);
+        assert(ret_event);
+        assert(ret_monitor);
+
+        r = sd_event_default(&event);
+        if (r < 0)
+                return log_error_errno(r, "Failed to allocate event loop: %m");
+
+        r = sd_event_add_time_relative(event, NULL, CLOCK_MONOTONIC, arg_token_timeout_usec, USEC_PER_SEC, NULL, INT_TO_PTR(-ETIMEDOUT));
+        if (r < 0)
+                return log_error_errno(r, "Failed to install timeout event source: %m");
 
         r = sd_device_monitor_new(&monitor);
         if (r < 0)
@@ -1181,7 +1232,8 @@ static int make_tpm2_device_monitor(sd_event *event, sd_device_monitor **ret) {
         if (r < 0)
                 return log_error_errno(r, "Failed to start device monitor: %m");
 
-        *ret = TAKE_PTR(monitor);
+        *ret_event = TAKE_PTR(event);
+        *ret_monitor = TAKE_PTR(monitor);
         return 0;
 }
 
@@ -1238,8 +1290,6 @@ static int attach_luks_or_plain_or_bitlk_by_tpm2(
                 return log_oom();
 
         for (;;) {
-                bool processed = false;
-
                 if (key_file || key_data) {
                         /* If key data is specified, use that */
 
@@ -1343,11 +1393,7 @@ static int attach_luks_or_plain_or_bitlk_by_tpm2(
                                 return log_notice_errno(SYNTHETIC_ERRNO(EAGAIN),
                                                         "No TPM2 hardware discovered and EFI bios indicates no support for it either, assuming TPM2-less system, falling back to traditional unocking.");
 
-                        r = sd_event_default(&event);
-                        if (r < 0)
-                                return log_error_errno(r, "Failed to allocate event loop: %m");
-
-                        r = make_tpm2_device_monitor(event, &monitor);
+                        r = make_tpm2_device_monitor(&event, &monitor);
                         if (r < 0)
                                 return r;
 
@@ -1358,17 +1404,9 @@ static int attach_luks_or_plain_or_bitlk_by_tpm2(
                         continue;
                 }
 
-                for (;;) {
-                        /* Wait for one event, and then eat all subsequent events until there are no
-                         * further ones */
-                        r = sd_event_run(event, processed ? 0 : UINT64_MAX);
-                        if (r < 0)
-                                return log_error_errno(r, "Failed to run event loop: %m");
-                        if (r == 0)
-                                break;
-
-                        processed = true;
-                }
+                r = run_security_device_monitor(event, monitor);
+                if (r < 0)
+                        return r;
 
                 log_debug("Got one or more potentially relevant udev events, rescanning for TPM2...");
         }
index 7fa4b85be7fa0d420293a96365a8c7cd77168190..940b661b0e5f9808eb4f5418d9de864186701fcc 100644 (file)
@@ -61,6 +61,7 @@
         #endif
 
         #define memcpy(a, b, c) CopyMem((a), (b), (c))
+        #define free(a) FreePool(a)
 #endif
 
 #if defined(static_assert)
  * @x: a string literal.
  */
 #define STRLEN(x) (sizeof(""x"") - sizeof(typeof(x[0])))
+
+#define mfree(memory)                           \
+        ({                                      \
+                free(memory);                   \
+                (typeof(memory)) NULL;          \
+        })
diff --git a/src/fuzz/fuzz-fido-id-desc.dict b/src/fuzz/fuzz-fido-id-desc.dict
deleted file mode 100644 (file)
index d2d2679..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-"\xfe"
-"\x00"
-"\x01"
-"\xf1"
-"\xd0"
-"\xf1\xd0\x00\x01"
index d5b699a2424e676b189538722c2235340ff08b35..3af1381eb427ffd9aa105112c50d24f67ac8f2d3 100644 (file)
@@ -2131,6 +2131,7 @@ static int help(int argc, char *argv[], void *userdata) {
                "     --storage=STORAGE         Storage type to use (luks, fscrypt, directory,\n"
                "                               subvolume, cifs)\n"
                "     --image-path=PATH         Path to image file/directory\n"
+               "     --drop-caches=BOOL        Whether to automatically drop caches on logout\n"
                "\n%4$sLUKS Storage User Record Properties:%5$s\n"
                "     --fs-type=TYPE            File system type to use in case of luks\n"
                "                               storage (btrfs, ext4, xfs)\n"
@@ -2245,6 +2246,7 @@ static int parse_argv(int argc, char *argv[]) {
                 ARG_RECOVERY_KEY,
                 ARG_AND_RESIZE,
                 ARG_AND_CHANGE_PASSWORD,
+                ARG_DROP_CACHES,
         };
 
         static const struct option options[] = {
@@ -2327,6 +2329,7 @@ static int parse_argv(int argc, char *argv[]) {
                 { "recovery-key",                required_argument, NULL, ARG_RECOVERY_KEY                },
                 { "and-resize",                  required_argument, NULL, ARG_AND_RESIZE                  },
                 { "and-change-password",         required_argument, NULL, ARG_AND_CHANGE_PASSWORD         },
+                { "drop-caches",                 required_argument, NULL, ARG_DROP_CACHES                 },
                 {}
         };
 
@@ -3450,6 +3453,26 @@ static int parse_argv(int argc, char *argv[]) {
                         arg_and_change_password = true;
                         break;
 
+                case ARG_DROP_CACHES: {
+                        bool drop_caches;
+
+                        if (isempty(optarg)) {
+                                r = drop_from_identity("dropCaches");
+                                if (r < 0)
+                                        return r;
+                        }
+
+                        r = parse_boolean_argument("--drop-caches=", optarg, &drop_caches);
+                        if (r < 0)
+                                return r;
+
+                        r = json_variant_set_field_boolean(&arg_identity_extra, "dropCaches", r);
+                        if (r < 0)
+                                return log_error_errno(r, "Failed to set drop caches field: %m");
+
+                        break;
+                }
+
                 case '?':
                         return -EINVAL;
 
index bbdc6940f3da0f0db4e0fc3a871655233eb98d01..d8f192650efac3ecf28801f16638d97933f779e5 100644 (file)
@@ -38,6 +38,9 @@
 #include "user-record.h"
 #include "user-util.h"
 
+/* Retry to deactivate home directories again and again every 15s until it works */
+#define RETRY_DEACTIVATE_USEC (15U * USEC_PER_SEC)
+
 #define HOME_USERS_MAX 500
 #define PENDING_OPERATIONS_MAX 100
 
@@ -130,6 +133,8 @@ int home_new(Manager *m, UserRecord *hr, const char *sysfs, Home **ret) {
                 .worker_stdout_fd = -1,
                 .sysfs = TAKE_PTR(ns),
                 .signed_locally = -1,
+                .pin_fd = -1,
+                .luks_lock_fd = -1,
         };
 
         r = hashmap_put(m->homes_by_name, home->user_name, home);
@@ -203,6 +208,11 @@ Home *home_free(Home *h) {
 
         h->current_operation = operation_unref(h->current_operation);
 
+        safe_close(h->pin_fd);
+        safe_close(h->luks_lock_fd);
+
+        h->retry_deactivate_event_source = sd_event_source_disable_unref(h->retry_deactivate_event_source);
+
         return mfree(h);
 }
 
@@ -317,6 +327,141 @@ int home_unlink_record(Home *h) {
         return 0;
 }
 
+static void home_unpin(Home *h) {
+        assert(h);
+
+        if (h->pin_fd < 0)
+                return;
+
+        h->pin_fd = safe_close(h->pin_fd);
+        log_debug("Successfully closed pin fd on home for %s.", h->user_name);
+}
+
+static void home_pin(Home *h) {
+        const char *path;
+
+        assert(h);
+
+        if (h->pin_fd >= 0) /* Already pinned? */
+                return;
+
+        path = user_record_home_directory(h->record);
+        if (!path) {
+                log_warning("No home directory path to pin for %s, ignoring.", h->user_name);
+                return;
+        }
+
+        h->pin_fd = open(path, O_RDONLY|O_DIRECTORY|O_CLOEXEC);
+        if (h->pin_fd < 0) {
+                log_warning_errno(errno, "Couldn't open home directory '%s' for pinning, ignoring: %m", path);
+                return;
+        }
+
+        log_debug("Successfully pinned home directory '%s'.", path);
+}
+
+static void home_update_pin_fd(Home *h, HomeState state) {
+        assert(h);
+
+        if (state < 0)
+                state = home_get_state(h);
+
+        return HOME_STATE_SHALL_PIN(state) ? home_pin(h) : home_unpin(h);
+}
+
+static void home_maybe_close_luks_lock_fd(Home *h, HomeState state) {
+        assert(h);
+
+        if (h->luks_lock_fd < 0)
+                return;
+
+        if (state < 0)
+                state = home_get_state(h);
+
+        /* Keep the lock as long as the home dir is active or has some operation going */
+        if (HOME_STATE_IS_EXECUTING_OPERATION(state) || HOME_STATE_IS_ACTIVE(state) || state == HOME_LOCKED)
+                return;
+
+        h->luks_lock_fd = safe_close(h->luks_lock_fd);
+        log_debug("Successfully closed LUKS backing file lock for %s.", h->user_name);
+}
+
+static void home_maybe_stop_retry_deactivate(Home *h, HomeState state) {
+        assert(h);
+
+        /* Free the deactivation retry event source if we won't need it anymore. Specifically, we'll free the
+         * event source whenever the home directory is already deactivated (and we thus where successful) or
+         * if we start executing an operation that indicates that the home directory is going to be used or
+         * operated on again. Also, if the home is referenced again stop the timer */
+
+        if (HOME_STATE_MAY_RETRY_DEACTIVATE(state) &&
+            !h->ref_event_source_dont_suspend &&
+            !h->ref_event_source_please_suspend)
+                return;
+
+        h->retry_deactivate_event_source = sd_event_source_disable_unref(h->retry_deactivate_event_source);
+}
+
+static int home_deactivate_internal(Home *h, bool force, sd_bus_error *error);
+static void home_start_retry_deactivate(Home *h);
+
+static int home_on_retry_deactivate(sd_event_source *s, uint64_t usec, void *userdata) {
+        Home *h = userdata;
+        HomeState state;
+
+        assert(s);
+        assert(h);
+
+        /* 15s after the last attempt to deactivate the home directory passed. Let's try it one more time. */
+
+        h->retry_deactivate_event_source = sd_event_source_disable_unref(h->retry_deactivate_event_source);
+
+        state = home_get_state(h);
+        if (!HOME_STATE_MAY_RETRY_DEACTIVATE(state))
+                return 0;
+
+        if (IN_SET(state, HOME_ACTIVE, HOME_LINGERING)) {
+                log_info("Again trying to deactivate home directory.");
+
+                /* If we are not executing any operation, let's start deactivating now. Note that this will
+                 * restart our timer again, we are gonna be called again if this doesn't work. */
+                (void) home_deactivate_internal(h, /* force= */ false, NULL);
+        } else
+                /* if we are executing an operation (specifically, area already running a deactivation
+                 * operation), then simply reque the timer, so that we retry again. */
+                home_start_retry_deactivate(h);
+
+        return 0;
+}
+
+static void home_start_retry_deactivate(Home *h) {
+        int r;
+
+        assert(h);
+        assert(h->manager);
+
+        /* Alrady allocated? */
+        if (h->retry_deactivate_event_source)
+                return;
+
+        /* If the home directory is being used now don't start the timer */
+        if (h->ref_event_source_dont_suspend || h->ref_event_source_please_suspend)
+                return;
+
+        r = sd_event_add_time_relative(
+                        h->manager->event,
+                        &h->retry_deactivate_event_source,
+                        CLOCK_MONOTONIC,
+                        RETRY_DEACTIVATE_USEC,
+                        1*USEC_PER_MINUTE,
+                        home_on_retry_deactivate,
+                        h);
+        if (r < 0)
+                return (void) log_warning_errno(r, "Failed to install retry-deactivate event source, ignoring: %m");
+
+        (void) sd_event_source_set_description(h->retry_deactivate_event_source, "retry-deactivate");
+}
+
 static void home_set_state(Home *h, HomeState state) {
         HomeState old_state, new_state;
 
@@ -331,6 +476,10 @@ static void home_set_state(Home *h, HomeState state) {
                  home_state_to_string(old_state),
                  home_state_to_string(new_state));
 
+        home_update_pin_fd(h, new_state);
+        home_maybe_close_luks_lock_fd(h, new_state);
+        home_maybe_stop_retry_deactivate(h, new_state);
+
         if (HOME_STATE_IS_EXECUTING_OPERATION(old_state) && !HOME_STATE_IS_EXECUTING_OPERATION(new_state)) {
                 /* If we just finished executing some operation, process the queue of pending operations. And
                  * enqueue it for GC too. */
@@ -483,6 +632,8 @@ static int convert_worker_errno(Home *h, int e, sd_bus_error *error) {
                 return sd_bus_error_setf(error, BUS_ERROR_NO_DISK_SPACE, "Not enough disk space for home %s", h->user_name);
         case -EKEYREVOKED:
                 return sd_bus_error_setf(error, BUS_ERROR_HOME_CANT_AUTHENTICATE, "Home %s has no password or other authentication mechanism defined.", h->user_name);
+        case -EADDRINUSE:
+                return sd_bus_error_setf(error, BUS_ERROR_HOME_IN_USE, "Home %s is currently being used elsewhere.", h->user_name);
         }
 
         return 0;
@@ -1029,6 +1180,12 @@ static int home_start_work(Home *h, const char *verb, UserRecord *hr, UserRecord
                         _exit(EXIT_FAILURE);
                 }
 
+                /* If we haven't locked the device yet, ask for a lock to be taken and be passed back to us via sd_notify(). */
+                if (setenv("SYSTEMD_LUKS_LOCK", one_zero(h->luks_lock_fd < 0), 1) < 0) {
+                        log_error_errno(errno, "Failed to set $SYSTEMD_LUKS_LOCK: %m");
+                        _exit(EXIT_FAILURE);
+                }
+
                 if (h->manager->default_storage >= 0)
                         if (setenv("SYSTEMD_HOME_DEFAULT_STORAGE", user_storage_to_string(h->manager->default_storage), 1) < 0) {
                                 log_error_errno(errno, "Failed to set $SYSTEMD_HOME_DEFAULT_STORAGE: %m");
@@ -1149,6 +1306,7 @@ int home_fixate(Home *h, UserRecord *secret, sd_bus_error *error) {
         case HOME_INACTIVE:
         case HOME_DIRTY:
         case HOME_ACTIVE:
+        case HOME_LINGERING:
         case HOME_LOCKED:
                 return sd_bus_error_setf(error, BUS_ERROR_HOME_ALREADY_FIXATED, "Home %s is already fixated.", h->user_name);
         case HOME_UNFIXATED:
@@ -1190,6 +1348,11 @@ int home_activate(Home *h, UserRecord *secret, sd_bus_error *error) {
                 return sd_bus_error_setf(error, BUS_ERROR_HOME_ABSENT, "Home %s is currently missing or not plugged in.", h->user_name);
         case HOME_ACTIVE:
                 return sd_bus_error_setf(error, BUS_ERROR_HOME_ALREADY_ACTIVE, "Home %s is already active.", h->user_name);
+        case HOME_LINGERING:
+                /* If we are lingering, i.e. active but are supposed to be deactivated, then cancel this
+                 * timer if the user explicitly asks us to be active */
+                h->retry_deactivate_event_source = sd_event_source_disable_unref(h->retry_deactivate_event_source);
+                return 0;
         case HOME_LOCKED:
                 return sd_bus_error_setf(error, BUS_ERROR_HOME_LOCKED, "Home %s is currently locked.", h->user_name);
         case HOME_INACTIVE:
@@ -1236,6 +1399,7 @@ int home_authenticate(Home *h, UserRecord *secret, sd_bus_error *error) {
         case HOME_INACTIVE:
         case HOME_DIRTY:
         case HOME_ACTIVE:
+        case HOME_LINGERING:
                 break;
         default:
                 return sd_bus_error_setf(error, BUS_ERROR_HOME_BUSY, "An operation on home %s is currently being executed.", h->user_name);
@@ -1245,7 +1409,7 @@ int home_authenticate(Home *h, UserRecord *secret, sd_bus_error *error) {
         if (r < 0)
                 return r;
 
-        return home_authenticate_internal(h, secret, state == HOME_ACTIVE ? HOME_AUTHENTICATING_WHILE_ACTIVE : HOME_AUTHENTICATING, error);
+        return home_authenticate_internal(h, secret, HOME_STATE_IS_ACTIVE(state) ? HOME_AUTHENTICATING_WHILE_ACTIVE : HOME_AUTHENTICATING, error);
 }
 
 static int home_deactivate_internal(Home *h, bool force, sd_bus_error *error) {
@@ -1253,12 +1417,22 @@ static int home_deactivate_internal(Home *h, bool force, sd_bus_error *error) {
 
         assert(h);
 
+        home_unpin(h); /* unpin so that we can deactivate */
+
         r = home_start_work(h, force ? "deactivate-force" : "deactivate", h->record, NULL);
         if (r < 0)
-                return r;
+                /* Operation failed before it even started, reacquire pin fd, if state still dictates so */
+                home_update_pin_fd(h, _HOME_STATE_INVALID);
+        else {
+                home_set_state(h, HOME_DEACTIVATING);
+                r = 0;
+        }
 
-        home_set_state(h, HOME_DEACTIVATING);
-        return 0;
+        /* Let's start a timer to retry deactivation in 15. We'll stop the timer once we manage to deactivate
+         * the home directory again, or we we start any other operation. */
+        home_start_retry_deactivate(h);
+
+        return r;
 }
 
 int home_deactivate(Home *h, bool force, sd_bus_error *error) {
@@ -1273,6 +1447,7 @@ int home_deactivate(Home *h, bool force, sd_bus_error *error) {
         case HOME_LOCKED:
                 return sd_bus_error_setf(error, BUS_ERROR_HOME_LOCKED, "Home %s is currently locked.", h->user_name);
         case HOME_ACTIVE:
+        case HOME_LINGERING:
                 break;
         default:
                 return sd_bus_error_setf(error, BUS_ERROR_HOME_BUSY, "An operation on home %s is currently being executed.", h->user_name);
@@ -1309,6 +1484,7 @@ int home_create(Home *h, UserRecord *secret, sd_bus_error *error) {
         case HOME_ABSENT:
                 break;
         case HOME_ACTIVE:
+        case HOME_LINGERING:
         case HOME_LOCKED:
         default:
                 return sd_bus_error_setf(error, BUS_ERROR_HOME_BUSY, "Home %s is currently being used, or an operation on home %s is currently being executed.", h->user_name, h->user_name);
@@ -1347,6 +1523,7 @@ int home_remove(Home *h, sd_bus_error *error) {
         case HOME_DIRTY:
                 break;
         case HOME_ACTIVE:
+        case HOME_LINGERING:
         default:
                 return sd_bus_error_setf(error, BUS_ERROR_HOME_BUSY, "Home %s is currently being used, or an operation on home %s is currently being executed.", h->user_name, h->user_name);
         }
@@ -1485,6 +1662,7 @@ int home_update(Home *h, UserRecord *hr, sd_bus_error *error) {
         case HOME_INACTIVE:
         case HOME_DIRTY:
         case HOME_ACTIVE:
+        case HOME_LINGERING:
                 break;
         default:
                 return sd_bus_error_setf(error, BUS_ERROR_HOME_BUSY, "An operation on home %s is currently being executed.", h->user_name);
@@ -1498,7 +1676,7 @@ int home_update(Home *h, UserRecord *hr, sd_bus_error *error) {
         if (r < 0)
                 return r;
 
-        home_set_state(h, state == HOME_ACTIVE ? HOME_UPDATING_WHILE_ACTIVE : HOME_UPDATING);
+        home_set_state(h, HOME_STATE_IS_ACTIVE(state) ? HOME_UPDATING_WHILE_ACTIVE : HOME_UPDATING);
         return 0;
 }
 
@@ -1520,6 +1698,7 @@ int home_resize(Home *h, uint64_t disk_size, UserRecord *secret, sd_bus_error *e
         case HOME_INACTIVE:
         case HOME_DIRTY:
         case HOME_ACTIVE:
+        case HOME_LINGERING:
                 break;
         default:
                 return sd_bus_error_setf(error, BUS_ERROR_HOME_BUSY, "An operation on home %s is currently being executed.", h->user_name);
@@ -1568,7 +1747,7 @@ int home_resize(Home *h, uint64_t disk_size, UserRecord *secret, sd_bus_error *e
         if (r < 0)
                 return r;
 
-        home_set_state(h, state == HOME_ACTIVE ? HOME_RESIZING_WHILE_ACTIVE : HOME_RESIZING);
+        home_set_state(h, HOME_STATE_IS_ACTIVE(state) ? HOME_RESIZING_WHILE_ACTIVE : HOME_RESIZING);
         return 0;
 }
 
@@ -1616,6 +1795,7 @@ int home_passwd(Home *h,
         case HOME_INACTIVE:
         case HOME_DIRTY:
         case HOME_ACTIVE:
+        case HOME_LINGERING:
                 break;
         default:
                 return sd_bus_error_setf(error, BUS_ERROR_HOME_BUSY, "An operation on home %s is currently being executed.", h->user_name);
@@ -1681,7 +1861,7 @@ int home_passwd(Home *h,
         if (r < 0)
                 return r;
 
-        home_set_state(h, state == HOME_ACTIVE ? HOME_PASSWD_WHILE_ACTIVE : HOME_PASSWD);
+        home_set_state(h, HOME_STATE_IS_ACTIVE(state) ? HOME_PASSWD_WHILE_ACTIVE : HOME_PASSWD);
         return 0;
 }
 
@@ -1700,6 +1880,7 @@ int home_unregister(Home *h, sd_bus_error *error) {
         case HOME_DIRTY:
                 break;
         case HOME_ACTIVE:
+        case HOME_LINGERING:
         default:
                 return sd_bus_error_setf(error, BUS_ERROR_HOME_BUSY, "Home %s is currently being used, or an operation on home %s is currently being executed.", h->user_name, h->user_name);
         }
@@ -1727,6 +1908,7 @@ int home_lock(Home *h, sd_bus_error *error) {
         case HOME_LOCKED:
                 return sd_bus_error_setf(error, BUS_ERROR_HOME_LOCKED, "Home %s is already locked.", h->user_name);
         case HOME_ACTIVE:
+        case HOME_LINGERING:
                 break;
         default:
                 return sd_bus_error_setf(error, BUS_ERROR_HOME_BUSY, "An operation on home %s is currently being executed.", h->user_name);
@@ -1767,6 +1949,7 @@ int home_unlock(Home *h, UserRecord *secret, sd_bus_error *error) {
         case HOME_ABSENT:
         case HOME_INACTIVE:
         case HOME_ACTIVE:
+        case HOME_LINGERING:
         case HOME_DIRTY:
                 return sd_bus_error_setf(error, BUS_ERROR_HOME_NOT_LOCKED, "Home %s is not locked.", h->user_name);
         case HOME_LOCKED:
@@ -1789,7 +1972,7 @@ HomeState home_get_state(Home *h) {
         /* Otherwise, let's see if the home directory is mounted. If so, we assume for sure the home
          * directory is active */
         if (user_record_test_home_directory(h->record) == USER_TEST_MOUNTED)
-                return HOME_ACTIVE;
+                return h->retry_deactivate_event_source ? HOME_LINGERING : HOME_ACTIVE;
 
         /* And if we see the image being gone, we report this as absent */
         r = user_record_test_image_path(h->record);
@@ -1802,28 +1985,49 @@ HomeState home_get_state(Home *h) {
         return HOME_INACTIVE;
 }
 
-void home_process_notify(Home *h, char **l) {
+void home_process_notify(Home *h, char **l, int fd) {
+        _cleanup_close_ int taken_fd = TAKE_FD(fd);
         const char *e;
         int error;
         int r;
 
         assert(h);
 
-        e = strv_env_get(l, "ERRNO");
-        if (!e) {
-                log_debug("Got notify message lacking ERRNO= field, ignoring.");
+        e = strv_env_get(l, "SYSTEMD_LUKS_LOCK_FD");
+        if (e) {
+                r = parse_boolean(e);
+                if (r < 0)
+                        return (void) log_debug_errno(r, "Failed to parse SYSTEMD_LUKS_LOCK_FD value: %m");
+                if (r > 0) {
+                        if (taken_fd < 0)
+                                return (void) log_debug("Got notify message with SYSTEMD_LUKS_LOCK_FD=1 but no fd passed, ignoring: %m");
+
+                        safe_close(h->luks_lock_fd);
+                        h->luks_lock_fd = TAKE_FD(taken_fd);
+
+                        log_debug("Successfully acquired LUKS lock fd from worker.");
+
+                        /* Immediately check if we actually want to keep it */
+                        home_maybe_close_luks_lock_fd(h, _HOME_STATE_INVALID);
+                } else {
+                        if (taken_fd >= 0)
+                                return (void) log_debug("Got notify message with SYSTEMD_LUKS_LOCK_FD=0 but fd passed, ignoring: %m");
+
+                        h->luks_lock_fd = safe_close(h->luks_lock_fd);
+                }
+
                 return;
         }
 
+        e = strv_env_get(l, "ERRNO");
+        if (!e)
+                return (void) log_debug("Got notify message lacking both ERRNO= and SYSTEMD_LUKS_LOCK_FD= field, ignoring.");
+
         r = safe_atoi(e, &error);
-        if (r < 0) {
-                log_debug_errno(r, "Failed to parse received error number, ignoring: %s", e);
-                return;
-        }
-        if (error <= 0) {
-                log_debug("Error number is out of range: %i", error);
-                return;
-        }
+        if (r < 0)
+                return (void) log_debug_errno(r, "Failed to parse received error number, ignoring: %s", e);
+        if (error <= 0)
+                return (void) log_debug("Error number is out of range: %i", error);
 
         h->worker_error_code = error;
 }
@@ -2372,6 +2576,7 @@ static int home_dispatch_acquire(Home *h, Operation *o) {
                 break;
 
         case HOME_ACTIVE:
+        case HOME_LINGERING:
                 for_state = HOME_AUTHENTICATING_FOR_ACQUIRE;
                 call = home_authenticate_internal;
                 break;
@@ -2426,6 +2631,7 @@ static int home_dispatch_release(Home *h, Operation *o) {
                         break;
 
                 case HOME_ACTIVE:
+                case HOME_LINGERING:
                         r = home_deactivate_internal(h, false, &error);
                         break;
 
@@ -2470,6 +2676,7 @@ static int home_dispatch_lock_all(Home *h, Operation *o) {
                 break;
 
         case HOME_ACTIVE:
+        case HOME_LINGERING:
                 log_info("Locking home %s.", h->user_name);
                 r = home_lock(h, &error);
                 break;
@@ -2514,6 +2721,7 @@ static int home_dispatch_deactivate_all(Home *h, Operation *o) {
                 break;
 
         case HOME_ACTIVE:
+        case HOME_LINGERING:
                 log_info("Deactivating home %s.", h->user_name);
                 r = home_deactivate_internal(h, false, &error);
                 break;
@@ -2559,6 +2767,7 @@ static int home_dispatch_pipe_eof(Home *h, Operation *o) {
                 break;
 
         case HOME_ACTIVE:
+        case HOME_LINGERING:
                 r = home_deactivate_internal(h, false, &error);
                 if (r < 0)
                         log_warning_errno(r, "Failed to deactivate %s, ignoring: %s", h->user_name, bus_error_message(&error, r));
@@ -2600,6 +2809,7 @@ static int home_dispatch_deactivate_force(Home *h, Operation *o) {
 
         case HOME_ACTIVE:
         case HOME_LOCKED:
+        case HOME_LINGERING:
                 r = home_deactivate_internal(h, true, &error);
                 if (r < 0)
                         log_warning_errno(r, "Failed to forcibly deactivate %s, ignoring: %s", h->user_name, bus_error_message(&error, r));
@@ -2820,6 +3030,7 @@ static const char* const home_state_table[_HOME_STATE_MAX] = {
         [HOME_ACTIVATING_FOR_ACQUIRE]      = "activating-for-acquire",
         [HOME_DEACTIVATING]                = "deactivating",
         [HOME_ACTIVE]                      = "active",
+        [HOME_LINGERING]                   = "lingering",
         [HOME_LOCKING]                     = "locking",
         [HOME_LOCKED]                      = "locked",
         [HOME_UNLOCKING]                   = "unlocking",
index 7f531a234c813ea3d2ead60cd2dd18ca36fb3287..7cd8a9edb40e0499800e4afd44eea53076ab31aa 100644 (file)
@@ -21,6 +21,7 @@ typedef enum HomeState {
         HOME_ACTIVATING_FOR_ACQUIRE,  /* activating because Acquire() was called */
         HOME_DEACTIVATING,
         HOME_ACTIVE,                  /* logged in right now */
+        HOME_LINGERING,               /* not logged in anymore, but we didn't manage to deactivate (because some process keeps it busy?) but we'll keep trying */
         HOME_LOCKING,
         HOME_LOCKED,
         HOME_UNLOCKING,
@@ -43,6 +44,7 @@ typedef enum HomeState {
 static inline bool HOME_STATE_IS_ACTIVE(HomeState state) {
         return IN_SET(state,
                       HOME_ACTIVE,
+                      HOME_LINGERING,
                       HOME_UPDATING_WHILE_ACTIVE,
                       HOME_RESIZING_WHILE_ACTIVE,
                       HOME_PASSWD_WHILE_ACTIVE,
@@ -74,6 +76,33 @@ static inline bool HOME_STATE_IS_EXECUTING_OPERATION(HomeState state) {
                       HOME_AUTHENTICATING_FOR_ACQUIRE);
 }
 
+static inline bool HOME_STATE_SHALL_PIN(HomeState state) {
+        /* Like HOME_STATE_IS_ACTIVE() â€“ but HOME_LINGERING is missing! */
+        return IN_SET(state,
+                      HOME_ACTIVE,
+                      HOME_UPDATING_WHILE_ACTIVE,
+                      HOME_RESIZING_WHILE_ACTIVE,
+                      HOME_PASSWD_WHILE_ACTIVE,
+                      HOME_AUTHENTICATING_WHILE_ACTIVE,
+                      HOME_AUTHENTICATING_FOR_ACQUIRE);
+}
+
+static inline bool HOME_STATE_MAY_RETRY_DEACTIVATE(HomeState state) {
+        /* Indicates when to leave the deactivate retry timer active */
+        return IN_SET(state,
+                      HOME_ACTIVE,
+                      HOME_LINGERING,
+                      HOME_DEACTIVATING,
+                      HOME_LOCKING,
+                      HOME_UNLOCKING,
+                      HOME_UNLOCKING_FOR_ACQUIRE,
+                      HOME_UPDATING_WHILE_ACTIVE,
+                      HOME_RESIZING_WHILE_ACTIVE,
+                      HOME_PASSWD_WHILE_ACTIVE,
+                      HOME_AUTHENTICATING_WHILE_ACTIVE,
+                      HOME_AUTHENTICATING_FOR_ACQUIRE);
+}
+
 struct Home {
         Manager *manager;
         char *user_name;
@@ -126,6 +155,15 @@ struct Home {
 
         /* Used to coalesce bus PropertiesChanged events */
         sd_event_source *deferred_change_event_source;
+
+        /* An fd to the top-level home directory we keep while logged in, to keep the dir busy */
+        int pin_fd;
+
+        /* A time event used to repeatedly try to unmount home dir after use if it didn't work on first try */
+        sd_event_source *retry_deactivate_event_source;
+
+        /* An fd that locks the backing file of LUKS home dirs with a BSD lock. */
+        int luks_lock_fd;
 };
 
 int home_new(Manager *m, UserRecord *hr, const char *sysfs, Home **ret);
@@ -152,7 +190,7 @@ int home_unlock(Home *h, UserRecord *secret, sd_bus_error *error);
 
 HomeState home_get_state(Home *h);
 
-void home_process_notify(Home *h, char **l);
+void home_process_notify(Home *h, char **l, int fd);
 
 int home_killall(Home *h);
 
index 070fd97d69bfbfa1d093ed61b4e88531598057c3..fbfbdaeb77ecf9f5ca6b6f65027b4d2b8540f5d1 100644 (file)
@@ -83,35 +83,38 @@ static void manager_watch_home(Manager *m) {
         m->inotify_event_source = sd_event_source_disable_unref(m->inotify_event_source);
         m->scan_slash_home = false;
 
-        if (statfs("/home/", &sfs) < 0) {
+        if (statfs(get_home_root(), &sfs) < 0) {
                 log_full_errno(errno == ENOENT ? LOG_DEBUG : LOG_WARNING, errno,
-                               "Failed to statfs() /home/ directory, disabling automatic scanning.");
+                               "Failed to statfs() %s directory, disabling automatic scanning.", get_home_root());
                 return;
         }
 
         if (is_network_fs(&sfs)) {
-                log_info("/home/ is a network file system, disabling automatic scanning.");
+                log_info("%s is a network file system, disabling automatic scanning.", get_home_root());
                 return;
         }
 
         if (is_fs_type(&sfs, AUTOFS_SUPER_MAGIC)) {
-                log_info("/home/ is on autofs, disabling automatic scanning.");
+                log_info("%s is on autofs, disabling automatic scanning.", get_home_root());
                 return;
         }
 
         m->scan_slash_home = true;
 
-        r = sd_event_add_inotify(m->event, &m->inotify_event_source, "/home/",
+        r = sd_event_add_inotify(m->event, &m->inotify_event_source, get_home_root(),
                                  IN_CREATE|IN_CLOSE_WRITE|IN_DELETE_SELF|IN_MOVE_SELF|IN_ONLYDIR|IN_MOVED_TO|IN_MOVED_FROM|IN_DELETE,
                                  on_home_inotify, m);
         if (r < 0)
                 log_full_errno(r == -ENOENT ? LOG_DEBUG : LOG_WARNING, r,
-                               "Failed to create inotify watch on /home/, ignoring.");
+                               "Failed to create inotify watch on %s, ignoring.", get_home_root());
 
         (void) sd_event_source_set_description(m->inotify_event_source, "home-inotify");
+
+        log_info("Watching %s.", get_home_root());
 }
 
 static int on_home_inotify(sd_event_source *s, const struct inotify_event *event, void *userdata) {
+        _cleanup_free_ char *j = NULL;
         Manager *m = userdata;
         const char *e, *n;
 
@@ -121,15 +124,15 @@ static int on_home_inotify(sd_event_source *s, const struct inotify_event *event
         if ((event->mask & (IN_Q_OVERFLOW|IN_MOVE_SELF|IN_DELETE_SELF|IN_IGNORED|IN_UNMOUNT)) != 0) {
 
                 if (FLAGS_SET(event->mask, IN_Q_OVERFLOW))
-                        log_debug("/home/ inotify queue overflow, rescanning.");
+                        log_debug("%s inotify queue overflow, rescanning.", get_home_root());
                 else if (FLAGS_SET(event->mask, IN_MOVE_SELF))
-                        log_info("/home/ moved or renamed, recreating watch and rescanning.");
+                        log_info("%s moved or renamed, recreating watch and rescanning.", get_home_root());
                 else if (FLAGS_SET(event->mask, IN_DELETE_SELF))
-                        log_info("/home/ deleted, recreating watch and rescanning.");
+                        log_info("%s deleted, recreating watch and rescanning.", get_home_root());
                 else if (FLAGS_SET(event->mask, IN_UNMOUNT))
-                        log_info("/home/ unmounted, recreating watch and rescanning.");
+                        log_info("%s unmounted, recreating watch and rescanning.", get_home_root());
                 else if (FLAGS_SET(event->mask, IN_IGNORED))
-                        log_info("/home/ watch invalidated, recreating watch and rescanning.");
+                        log_info("%s watch invalidated, recreating watch and rescanning.", get_home_root());
 
                 manager_watch_home(m);
                 (void) manager_gc_images(m);
@@ -146,19 +149,23 @@ static int on_home_inotify(sd_event_source *s, const struct inotify_event *event
         if (!e)
                 return 0;
 
-        n = strndupa(event->name, e - event->name);
+        n = strndupa_safe(event->name, e - event->name);
         if (!suitable_user_name(n))
                 return 0;
 
+        j = path_join(get_home_root(), event->name);
+        if (!j)
+                return log_oom();
+
         if ((event->mask & (IN_CREATE|IN_CLOSE_WRITE|IN_MOVED_TO)) != 0) {
                 if (FLAGS_SET(event->mask, IN_CREATE))
-                        log_debug("/home/%s has been created, having a look.", event->name);
+                        log_debug("%s has been created, having a look.", j);
                 else if (FLAGS_SET(event->mask, IN_CLOSE_WRITE))
-                        log_debug("/home/%s has been modified, having a look.", event->name);
+                        log_debug("%s has been modified, having a look.", j);
                 else if (FLAGS_SET(event->mask, IN_MOVED_TO))
-                        log_debug("/home/%s has been moved in, having a look.", event->name);
+                        log_debug("%s has been moved in, having a look.", j);
 
-                (void) manager_assess_image(m, -1, "/home/", event->name);
+                (void) manager_assess_image(m, -1, get_home_root(), event->name);
                 (void) bus_manager_emit_auto_login_changed(m);
         }
 
@@ -166,11 +173,11 @@ static int on_home_inotify(sd_event_source *s, const struct inotify_event *event
                 Home *h;
 
                 if (FLAGS_SET(event->mask, IN_DELETE))
-                        log_debug("/home/%s has been deleted, revalidating.", event->name);
+                        log_debug("%s has been deleted, revalidating.", j);
                 else if (FLAGS_SET(event->mask, IN_CLOSE_WRITE))
-                        log_debug("/home/%s has been closed after writing, revalidating.", event->name);
+                        log_debug("%s has been closed after writing, revalidating.", j);
                 else if (FLAGS_SET(event->mask, IN_MOVED_FROM))
-                        log_debug("/home/%s has been moved away, revalidating.", event->name);
+                        log_debug("%s has been moved away, revalidating.", j);
 
                 h = hashmap_get(m->homes_by_name, n);
                 if (h) {
@@ -487,7 +494,7 @@ static int search_quota(uid_t uid, const char *exclude_quota_path) {
          * comprehensive, but should cover most cases. Note that in an ideal world every user would be
          * registered in NSS and avoid our own UID range, but for all other cases, it's a good idea to be
          * paranoid and check quota if we can. */
-        FOREACH_STRING(where, "/home/", "/tmp/", "/var/", "/var/mail/", "/var/tmp/", "/var/spool/") {
+        FOREACH_STRING(where, get_home_root(), "/tmp/", "/var/", "/var/mail/", "/var/tmp/", "/var/spool/") {
                 struct dqblk req;
                 struct stat st;
 
@@ -914,13 +921,13 @@ int manager_enumerate_images(Manager *m) {
         if (!m->scan_slash_home)
                 return 0;
 
-        d = opendir("/home/");
+        d = opendir(get_home_root());
         if (!d)
                 return log_full_errno(errno == ENOENT ? LOG_DEBUG : LOG_ERR, errno,
-                                      "Failed to open /home/: %m");
+                                      "Failed to open %s: %m", get_home_root());
 
-        FOREACH_DIRENT(de, d, return log_error_errno(errno, "Failed to read /home/ directory: %m"))
-                (void) manager_assess_image(m, dirfd(d), "/home", de->d_name);
+        FOREACH_DIRENT(de, d, return log_error_errno(errno, "Failed to read %s directory: %m", get_home_root()))
+                (void) manager_assess_image(m, dirfd(d), get_home_root(), de->d_name);
 
         return 0;
 }
@@ -1010,13 +1017,25 @@ static int manager_bind_varlink(Manager *m) {
         return 0;
 }
 
-static ssize_t read_datagram(int fd, struct ucred *ret_sender, void **ret) {
+static ssize_t read_datagram(
+                int fd,
+                struct ucred *ret_sender,
+                void **ret,
+                int *ret_passed_fd) {
+
+        CMSG_BUFFER_TYPE(CMSG_SPACE(sizeof(struct ucred)) + CMSG_SPACE(sizeof(int))) control;
         _cleanup_free_ void *buffer = NULL;
+        _cleanup_close_ int passed_fd = -1;
+        struct ucred *sender = NULL;
+        struct cmsghdr *cmsg;
+        struct msghdr mh;
+        struct iovec iov;
         ssize_t n, m;
 
         assert(fd >= 0);
         assert(ret_sender);
         assert(ret);
+        assert(ret_passed_fd);
 
         n = next_datagram_size_fd(fd);
         if (n < 0)
@@ -1026,58 +1045,54 @@ static ssize_t read_datagram(int fd, struct ucred *ret_sender, void **ret) {
         if (!buffer)
                 return -ENOMEM;
 
-        if (ret_sender) {
-                CMSG_BUFFER_TYPE(CMSG_SPACE(sizeof(struct ucred))) control;
-                bool found_ucred = false;
-                struct cmsghdr *cmsg;
-                struct msghdr mh;
-                struct iovec iov;
+        /* Pass one extra byte, as a size check */
+        iov = IOVEC_MAKE(buffer, n + 1);
 
-                /* Pass one extra byte, as a size check */
-                iov = IOVEC_MAKE(buffer, n + 1);
-
-                mh = (struct msghdr) {
-                        .msg_iov = &iov,
-                        .msg_iovlen = 1,
-                        .msg_control = &control,
-                        .msg_controllen = sizeof(control),
-                };
+        mh = (struct msghdr) {
+                .msg_iov = &iov,
+                .msg_iovlen = 1,
+                .msg_control = &control,
+                .msg_controllen = sizeof(control),
+        };
 
-                m = recvmsg_safe(fd, &mh, MSG_DONTWAIT|MSG_CMSG_CLOEXEC);
-                if (m < 0)
-                        return m;
+        m = recvmsg_safe(fd, &mh, MSG_DONTWAIT|MSG_CMSG_CLOEXEC);
+        if (m < 0)
+                return m;
 
+        /* Ensure the size matches what we determined before */
+        if (m != n) {
                 cmsg_close_all(&mh);
+                return -EMSGSIZE;
+        }
 
-                /* Ensure the size matches what we determined before */
-                if (m != n)
-                        return -EMSGSIZE;
+        CMSG_FOREACH(cmsg, &mh) {
+                if (cmsg->cmsg_level == SOL_SOCKET &&
+                    cmsg->cmsg_type == SCM_CREDENTIALS &&
+                    cmsg->cmsg_len == CMSG_LEN(sizeof(struct ucred))) {
+                        assert(!sender);
+                        sender = (struct ucred*) CMSG_DATA(cmsg);
+                }
 
-                CMSG_FOREACH(cmsg, &mh)
-                        if (cmsg->cmsg_level == SOL_SOCKET &&
-                            cmsg->cmsg_type == SCM_CREDENTIALS &&
-                            cmsg->cmsg_len == CMSG_LEN(sizeof(struct ucred))) {
+                if (cmsg->cmsg_level == SOL_SOCKET &&
+                    cmsg->cmsg_type == SCM_RIGHTS) {
 
-                                memcpy(ret_sender, CMSG_DATA(cmsg), sizeof(struct ucred));
-                                found_ucred = true;
+                        if (cmsg->cmsg_len != CMSG_LEN(sizeof(int))) {
+                                cmsg_close_all(&mh);
+                                return -EMSGSIZE;
                         }
 
-                if (!found_ucred)
-                        *ret_sender = (struct ucred) {
-                                .pid = 0,
-                                .uid = UID_INVALID,
-                                .gid = GID_INVALID,
-                        };
-        } else {
-                m = recv(fd, buffer, n + 1, MSG_DONTWAIT);
-                if (m < 0)
-                        return -errno;
-
-                /* Ensure the size matches what we determined before */
-                if (m != n)
-                        return -EMSGSIZE;
+                        assert(passed_fd < 0);
+                        passed_fd = *(int*) CMSG_DATA(cmsg);
+                }
         }
 
+        if (sender)
+                *ret_sender = *sender;
+        else
+                *ret_sender = (struct ucred) UCRED_INVALID;
+
+        *ret_passed_fd = TAKE_FD(passed_fd);
+
         /* For safety reasons: let's always NUL terminate.  */
         ((char*) buffer)[n] = 0;
         *ret = TAKE_PTR(buffer);
@@ -1088,7 +1103,8 @@ static ssize_t read_datagram(int fd, struct ucred *ret_sender, void **ret) {
 static int on_notify_socket(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
         _cleanup_strv_free_ char **l = NULL;
         _cleanup_free_ void *datagram = NULL;
-        struct ucred sender;
+        _cleanup_close_ int passed_fd = -1;
+        struct ucred sender = UCRED_INVALID;
         Manager *m = userdata;
         ssize_t n;
         Home *h;
@@ -1096,7 +1112,7 @@ static int on_notify_socket(sd_event_source *s, int fd, uint32_t revents, void *
         assert(s);
         assert(m);
 
-        n = read_datagram(fd, &sender, &datagram);
+        n = read_datagram(fd, &sender, &datagram, &passed_fd);
         if (IN_SET(n, -EAGAIN, -EINTR))
                 return 0;
         if (n < 0)
@@ -1117,7 +1133,7 @@ static int on_notify_socket(sd_event_source *s, int fd, uint32_t revents, void *
         if (!l)
                 return log_oom();
 
-        home_process_notify(h, l);
+        home_process_notify(h, l, TAKE_FD(passed_fd));
         return 0;
 }
 
index 04a4db8a94ab0fb686de67a620cad7d974411fe1..3ac99f20ed35dafbc60eef2a40997e17521b58d0 100644 (file)
 #include "strv.h"
 #include "tmpfile-util.h"
 
-int home_prepare_cifs(
+int home_setup_cifs(
                 UserRecord *h,
-                bool already_activated,
+                HomeSetupFlags flags,
                 HomeSetup *setup) {
 
         assert(h);
         assert(setup);
         assert(user_record_storage(h) == USER_CIFS);
 
-        if (already_activated)
+        if (FLAGS_SET(flags, HOME_SETUP_ALREADY_ACTIVATED))
                 setup->root_fd = open(user_record_home_directory(h), O_RDONLY|O_CLOEXEC|O_DIRECTORY|O_NOFOLLOW);
         else {
                 bool mounted = false;
@@ -99,39 +99,40 @@ int home_prepare_cifs(
 
 int home_activate_cifs(
                 UserRecord *h,
+                HomeSetup *setup,
                 PasswordCache *cache,
                 UserRecord **ret_home) {
 
-        _cleanup_(home_setup_undo) HomeSetup setup = HOME_SETUP_INIT;
         _cleanup_(user_record_unrefp) UserRecord *new_home = NULL;
         const char *hdo, *hd;
         int r;
 
         assert(h);
         assert(user_record_storage(h) == USER_CIFS);
+        assert(setup);
         assert(ret_home);
 
         if (!h->cifs_service)
                 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "User record lacks CIFS service, refusing.");
 
         assert_se(hdo = user_record_home_directory(h));
-        hd = strdupa(hdo); /* copy the string out, since it might change later in the home record object */
+        hd = strdupa_safe(hdo); /* copy the string out, since it might change later in the home record object */
 
-        r = home_prepare_cifs(h, false, &setup);
+        r = home_setup_cifs(h, 0, setup);
         if (r < 0)
                 return r;
 
-        r = home_refresh(h, &setup, NULL, cache, NULL, &new_home);
+        r = home_refresh(h, setup, NULL, cache, NULL, &new_home);
         if (r < 0)
                 return r;
 
-        setup.root_fd = safe_close(setup.root_fd);
+        setup->root_fd = safe_close(setup->root_fd);
 
         r = home_move_mount(NULL, hd);
         if (r < 0)
                 return r;
 
-        setup.undo_mount = false;
+        setup->undo_mount = false;
 
         log_info("Everything completed.");
 
@@ -139,8 +140,7 @@ int home_activate_cifs(
         return 1;
 }
 
-int home_create_cifs(UserRecord *h, UserRecord **ret_home) {
-        _cleanup_(home_setup_undo) HomeSetup setup = HOME_SETUP_INIT;
+int home_create_cifs(UserRecord *h, HomeSetup *setup, UserRecord **ret_home) {
         _cleanup_(user_record_unrefp) UserRecord *new_home = NULL;
         _cleanup_(closedirp) DIR *d = NULL;
         _cleanup_close_ int copy = -1;
@@ -148,6 +148,7 @@ int home_create_cifs(UserRecord *h, UserRecord **ret_home) {
 
         assert(h);
         assert(user_record_storage(h) == USER_CIFS);
+        assert(setup);
         assert(ret_home);
 
         if (!h->cifs_service)
@@ -160,11 +161,11 @@ int home_create_cifs(UserRecord *h, UserRecord **ret_home) {
                 return log_error_errno(errno, "Unable to detect whether /sbin/mount.cifs exists: %m");
         }
 
-        r = home_prepare_cifs(h, false, &setup);
+        r = home_setup_cifs(h, 0, setup);
         if (r < 0)
                 return r;
 
-        copy = fcntl(setup.root_fd, F_DUPFD_CLOEXEC, 3);
+        copy = fcntl(setup->root_fd, F_DUPFD_CLOEXEC, 3);
         if (copy < 0)
                 return -errno;
 
@@ -178,11 +179,11 @@ int home_create_cifs(UserRecord *h, UserRecord **ret_home) {
         if (errno != 0)
                 return log_error_errno(errno, "Failed to detect if CIFS directory is empty: %m");
 
-        r = home_populate(h, setup.root_fd);
+        r = home_populate(h, setup->root_fd);
         if (r < 0)
                 return r;
 
-        r = home_sync_and_statfs(setup.root_fd, NULL);
+        r = home_sync_and_statfs(setup->root_fd, NULL);
         if (r < 0)
                 return r;
 
index da2e50a795a30dff063350ba8d571f08a11aafb4..dda1e0b876d41fb70630599b09ef500b0a5ccd4d 100644 (file)
@@ -4,8 +4,8 @@
 #include "homework.h"
 #include "user-record.h"
 
-int home_prepare_cifs(UserRecord *h, bool already_activated, HomeSetup *setup);
+int home_setup_cifs(UserRecord *h, HomeSetupFlags flags, HomeSetup *setup);
 
-int home_activate_cifs(UserRecord *h, PasswordCache *cache, UserRecord **ret_home);
+int home_activate_cifs(UserRecord *h, HomeSetup *setup, PasswordCache *cache, UserRecord **ret_home);
 
-int home_create_cifs(UserRecord *h, UserRecord **ret_home);
+int home_create_cifs(UserRecord *h, HomeSetup *setup, UserRecord **ret_home);
index 45a2fb9db78b72467b26f84b845b7b799033a34d..b95896d45b2bad2bb9a30a7af81c5be74f6ee5b1 100644 (file)
@@ -13,7 +13,7 @@
 #include "tmpfile-util.h"
 #include "umask-util.h"
 
-int home_prepare_directory(UserRecord *h, bool already_activated, HomeSetup *setup) {
+int home_setup_directory(UserRecord *h, HomeSetup *setup) {
         assert(h);
         assert(setup);
 
@@ -26,33 +26,34 @@ int home_prepare_directory(UserRecord *h, bool already_activated, HomeSetup *set
 
 int home_activate_directory(
                 UserRecord *h,
+                HomeSetup *setup,
                 PasswordCache *cache,
                 UserRecord **ret_home) {
 
         _cleanup_(user_record_unrefp) UserRecord *new_home = NULL, *header_home = NULL;
-        _cleanup_(home_setup_undo) HomeSetup setup = HOME_SETUP_INIT;
         const char *hdo, *hd, *ipo, *ip;
         int r;
 
         assert(h);
         assert(IN_SET(user_record_storage(h), USER_DIRECTORY, USER_SUBVOLUME, USER_FSCRYPT));
+        assert(setup);
         assert(ret_home);
 
         assert_se(ipo = user_record_image_path(h));
-        ip = strdupa(ipo); /* copy out, since reconciliation might cause changing of the field */
+        ip = strdupa_safe(ipo); /* copy out, since reconciliation might cause changing of the field */
 
         assert_se(hdo = user_record_home_directory(h));
-        hd = strdupa(hdo);
+        hd = strdupa_safe(hdo);
 
-        r = home_prepare(h, false, cache, &setup, &header_home);
+        r = home_setup(h, 0, cache, setup, &header_home);
         if (r < 0)
                 return r;
 
-        r = home_refresh(h, &setup, header_home, cache, NULL, &new_home);
+        r = home_refresh(h, setup, header_home, cache, NULL, &new_home);
         if (r < 0)
                 return r;
 
-        setup.root_fd = safe_close(setup.root_fd);
+        setup->root_fd = safe_close(setup->root_fd);
 
         /* Create mount point to mount over if necessary */
         if (!path_equal(ip, hd))
@@ -192,7 +193,7 @@ int home_create_directory_or_subvolume(UserRecord *h, UserRecord **ret_home) {
 
 int home_resize_directory(
                 UserRecord *h,
-                bool already_activated,
+                HomeSetupFlags flags,
                 PasswordCache *cache,
                 HomeSetup *setup,
                 UserRecord **ret_home) {
@@ -205,7 +206,7 @@ int home_resize_directory(
         assert(ret_home);
         assert(IN_SET(user_record_storage(h), USER_DIRECTORY, USER_SUBVOLUME, USER_FSCRYPT));
 
-        r = home_prepare(h, already_activated, cache, setup, NULL);
+        r = home_setup(h, flags, cache, setup, NULL);
         if (r < 0)
                 return r;
 
@@ -231,7 +232,7 @@ int home_resize_directory(
         if (r < 0)
                 return r;
 
-        r = home_setup_undo(setup);
+        r = home_setup_done(setup);
         if (r < 0)
                 return r;
 
index 27d640f380398e2a8599497e51b87c9105005fac..98b1804774828f9a8f1c4dfe766e2c35e470a063 100644 (file)
@@ -4,7 +4,7 @@
 #include "homework.h"
 #include "user-record.h"
 
-int home_prepare_directory(UserRecord *h, bool already_activated, HomeSetup *setup);
-int home_activate_directory(UserRecord *h, PasswordCache *cache, UserRecord **ret_home);
+int home_setup_directory(UserRecord *h, HomeSetup *setup);
+int home_activate_directory(UserRecord *h, HomeSetup *setup, PasswordCache *cache, UserRecord **ret_home);
 int home_create_directory_or_subvolume(UserRecord *h, UserRecord **ret_home);
-int home_resize_directory(UserRecord *h, bool already_activated, PasswordCache *cache, HomeSetup *setup, UserRecord **ret_home);
+int home_resize_directory(UserRecord *h, HomeSetupFlags flags, PasswordCache *cache, HomeSetup *setup, UserRecord **ret_home);
index 86dde4b78b0b730765a7b97fb6a27c3184d8aa01..899d4e10c6c777600acd058f8de3909746a3a3ff 100644 (file)
@@ -278,10 +278,9 @@ static int fscrypt_setup(
         return log_error_errno(SYNTHETIC_ERRNO(ENOKEY), "Failed to set up home directory with provided passwords.");
 }
 
-int home_prepare_fscrypt(
+int home_setup_fscrypt(
                 UserRecord *h,
-                bool already_activated,
-                PasswordCache *cache,
+                const PasswordCache *cache,
                 HomeSetup *setup) {
 
         _cleanup_(erase_and_freep) void *volume_key = NULL;
@@ -585,7 +584,7 @@ int home_create_fscrypt(
 int home_passwd_fscrypt(
                 UserRecord *h,
                 HomeSetup *setup,
-                PasswordCache *cache,               /* the passwords acquired via PKCS#11/FIDO2 security tokens */
+                const PasswordCache *cache,         /* the passwords acquired via PKCS#11/FIDO2 security tokens */
                 char **effective_passwords          /* new passwords */) {
 
         _cleanup_(erase_and_freep) void *volume_key = NULL;
index 50b03993e03d0c75f4cc0fc1d68123578b2201d0..736bcb9dcd9df3975f460d4374f6b830a61c2f44 100644 (file)
@@ -4,7 +4,7 @@
 #include "homework.h"
 #include "user-record.h"
 
-int home_prepare_fscrypt(UserRecord *h, bool already_activated, PasswordCache *cache, HomeSetup *setup);
+int home_setup_fscrypt(UserRecord *h, const PasswordCache *cache, HomeSetup *setup);
 int home_create_fscrypt(UserRecord *h, char **effective_passwords, UserRecord **ret_home);
 
-int home_passwd_fscrypt(UserRecord *h, HomeSetup *setup, PasswordCache *cache, char **effective_passwords);
+int home_passwd_fscrypt(UserRecord *h, HomeSetup *setup, const PasswordCache *cache, char **effective_passwords);
index c9c2476ed6e4741609ce281d35566d2a0ac50160..05e2950b4b445741c217cd62d4b00e49d4176146 100644 (file)
@@ -8,11 +8,18 @@
 #include <sys/mount.h>
 #include <sys/xattr.h>
 
+#if HAVE_VALGRIND_MEMCHECK_H
+#include <valgrind/memcheck.h>
+#endif
+
+#include "sd-daemon.h"
+
 #include "blkid-util.h"
 #include "blockdev-util.h"
 #include "btrfs-util.h"
 #include "chattr-util.h"
 #include "dm-util.h"
+#include "env-util.h"
 #include "errno-util.h"
 #include "fd-util.h"
 #include "fileio.h"
@@ -342,7 +349,10 @@ static int luks_setup(
                 return log_oom();
 
         r = -ENOKEY;
-        FOREACH_POINTER(list, cache->pkcs11_passwords, cache->fido2_passwords, passwords) {
+        FOREACH_POINTER(list,
+                        cache ? cache->pkcs11_passwords : NULL,
+                        cache ? cache->fido2_passwords : NULL,
+                        passwords) {
                 r = luks_try_passwords(cd, list, vk, &vks);
                 if (r != -ENOKEY)
                         break;
@@ -377,7 +387,7 @@ static int luks_setup(
 static int luks_open(
                 const char *dm_name,
                 char **passwords,
-                PasswordCache *cache,
+                const PasswordCache *cache,
                 struct crypt_device **ret,
                 sd_id128_t *ret_found_uuid,
                 void **ret_volume_key,
@@ -428,7 +438,10 @@ static int luks_open(
                 return log_oom();
 
         r = -ENOKEY;
-        FOREACH_POINTER(list, cache->pkcs11_passwords, cache->fido2_passwords, passwords) {
+        FOREACH_POINTER(list,
+                        cache ? cache->pkcs11_passwords : NULL,
+                        cache ? cache->fido2_passwords : NULL,
+                        passwords) {
                 r = luks_try_passwords(cd, list, vk, &vks);
                 if (r != -ENOKEY)
                         break;
@@ -659,7 +672,7 @@ static int crypt_device_to_evp_cipher(struct crypt_device *cd, const EVP_CIPHER
 
         e = strchr(cipher_mode, '-');
         if (e)
-                cipher_mode = strndupa(cipher_mode, e - cipher_mode);
+                cipher_mode = strndupa_safe(cipher_mode, e - cipher_mode);
 
         r = sym_crypt_get_volume_key_size(cd);
         if (r <= 0)
@@ -1042,9 +1055,91 @@ int run_fallocate_by_path(const char *backing_path) {
         return run_fallocate(backing_fd, NULL);
 }
 
-int home_prepare_luks(
+static int lock_image_fd(int image_fd, const char *ip) {
+        int r;
+
+        /* If the $SYSTEMD_LUKS_LOCK environment variable is set we'll take an exclusive BSD lock on the
+         * image file, and send it to our parent. homed will keep it open to ensure no other instance of
+         * homed (across the network or such) will also mount the file. */
+
+        r = getenv_bool("SYSTEMD_LUKS_LOCK");
+        if (r == -ENXIO)
+                return 0;
+        if (r < 0)
+                return log_error_errno(r, "Failed to parse $SYSTEMD_LUKS_LOCK environment variable: %m");
+        if (r > 0) {
+                struct stat st;
+
+                if (fstat(image_fd, &st) < 0)
+                        return log_error_errno(errno, "Failed to stat image file: %m");
+                if (S_ISBLK(st.st_mode)) {
+                        /* Locking block devices doesn't really make sense, as this might interfear with
+                         * udev's workings, and these locks aren't network propagated anyway, hence not what
+                         * we are after here. */
+                        log_debug("Not locking image file '%s', since it's a block device.", ip);
+                        return 0;
+                }
+                r = stat_verify_regular(&st);
+                if (r < 0)
+                        return log_error_errno(r, "Image file to lock is not a regular file: %m");
+
+                if (flock(image_fd, LOCK_EX|LOCK_NB) < 0) {
+
+                        if (errno == EWOULDBLOCK)
+                                log_error_errno(errno, "Image file '%s' already locked, can't use.", ip);
+                        else
+                                log_error_errno(errno, "Failed to lock image file '%s': %m", ip);
+
+                        return errno != EWOULDBLOCK ? -errno : -EADDRINUSE; /* Make error recognizable */
+                }
+
+                log_info("Successfully locked image file '%s'.", ip);
+
+                /* Now send it to our parent to keep safe while the home dir is active */
+                r = sd_pid_notify_with_fds(0, false, "SYSTEMD_LUKS_LOCK_FD=1", &image_fd, 1);
+                if (r < 0)
+                        log_warning_errno(r, "Failed to send LUKS lock fd to parent, ignoring: %m");
+        }
+
+        return 0;
+}
+
+static int open_image_file(
+                UserRecord *h,
+                const char *force_image_path,
+                struct stat *ret_stat) {
+
+        _cleanup_close_ int image_fd = -1;
+        struct stat st;
+        const char *ip;
+        int r;
+
+        ip = force_image_path ?: user_record_image_path(h);
+
+        image_fd = open(ip, O_RDWR|O_CLOEXEC|O_NOCTTY|O_NONBLOCK);
+        if (image_fd < 0)
+                return log_error_errno(errno, "Failed to open image file %s: %m", ip);
+
+        if (fstat(image_fd, &st) < 0)
+                return log_error_errno(errno, "Failed to fstat() image file: %m");
+        if (!S_ISREG(st.st_mode) && !S_ISBLK(st.st_mode))
+                return log_error_errno(
+                                S_ISDIR(st.st_mode) ? SYNTHETIC_ERRNO(EISDIR) : SYNTHETIC_ERRNO(EBADFD),
+                                "Image file %s is not a regular file or block device: %m", ip);
+
+        r = lock_image_fd(image_fd, ip);
+        if (r < 0)
+                return r;
+
+        if (ret_stat)
+                *ret_stat = st;
+
+        return TAKE_FD(image_fd);
+}
+
+int home_setup_luks(
                 UserRecord *h,
-                bool already_activated,
+                HomeSetupFlags flags,
                 const char *force_image_path,
                 PasswordCache *cache,
                 HomeSetup *setup,
@@ -1055,12 +1150,12 @@ int home_prepare_luks(
         _cleanup_(loop_device_unrefp) LoopDevice *loop = NULL;
         _cleanup_(sym_crypt_freep) struct crypt_device *cd = NULL;
         _cleanup_(erase_and_freep) void *volume_key = NULL;
-        _cleanup_close_ int root_fd = -1, image_fd = -1;
+        _cleanup_close_ int opened_image_fd = -1, root_fd = -1;
         bool dm_activated = false, mounted = false;
         size_t volume_key_size = 0;
         bool marked_dirty = false;
         uint64_t offset, size;
-        int r;
+        int r, image_fd = -1;
 
         assert(h);
         assert(setup);
@@ -1073,7 +1168,7 @@ int home_prepare_luks(
         if (r < 0)
                 return r;
 
-        if (already_activated) {
+        if (FLAGS_SET(flags, HOME_SETUP_ALREADY_ACTIVATED)) {
                 struct loop_info64 info;
                 const char *n;
 
@@ -1141,6 +1236,10 @@ int home_prepare_luks(
                                 offset *= 512U;
                         }
                 } else {
+#if HAVE_VALGRIND_MEMCHECK_H
+                        VALGRIND_MAKE_MEM_DEFINED(&info, sizeof(info));
+#endif
+
                         offset = info.lo_offset;
                         size = info.lo_sizelimit;
                 }
@@ -1151,7 +1250,7 @@ int home_prepare_luks(
 
                 root_fd = open(user_record_home_directory(h), O_RDONLY|O_CLOEXEC|O_DIRECTORY|O_NOFOLLOW);
                 if (root_fd < 0) {
-                        r = log_error_errno(r, "Failed to open home directory: %m");
+                        r = log_error_errno(errno, "Failed to open home directory: %m");
                         goto fail;
                 }
         } else {
@@ -1165,16 +1264,15 @@ int home_prepare_luks(
                 if (!subdir)
                         return log_oom();
 
-                image_fd = open(ip, O_RDWR|O_CLOEXEC|O_NOCTTY|O_NONBLOCK);
-                if (image_fd < 0)
-                        return log_error_errno(errno, "Failed to open image file %s: %m", ip);
+                /* Reuse the image fd if it has already been opened by an earlier step */
+                if (setup->image_fd < 0) {
+                        opened_image_fd = open_image_file(h, force_image_path, &st);
+                        if (opened_image_fd < 0)
+                                return opened_image_fd;
 
-                if (fstat(image_fd, &st) < 0)
-                        return log_error_errno(errno, "Failed to fstat() image file: %m");
-                if (!S_ISREG(st.st_mode) && !S_ISBLK(st.st_mode))
-                        return log_error_errno(
-                                        S_ISDIR(st.st_mode) ? SYNTHETIC_ERRNO(EISDIR) : SYNTHETIC_ERRNO(EBADFD),
-                                        "Image file %s is not a regular file or block device: %m", ip);
+                        image_fd = opened_image_fd;
+                } else
+                        image_fd = setup->image_fd;
 
                 r = luks_validate(image_fd, user_record_user_name_and_realm(h), h->partition_uuid, &found_partition_uuid, &offset, &size);
                 if (r < 0)
@@ -1238,14 +1336,19 @@ int home_prepare_luks(
 
                 root_fd = open(subdir, O_RDONLY|O_CLOEXEC|O_DIRECTORY|O_NOFOLLOW);
                 if (root_fd < 0) {
-                        r = log_error_errno(r, "Failed to open home directory: %m");
+                        r = log_error_errno(errno, "Failed to open home directory: %m");
                         goto fail;
                 }
 
                 if (user_record_luks_discard(h))
                         (void) run_fitrim(root_fd);
 
-                setup->image_fd = TAKE_FD(image_fd);
+                /* And now, fill in everything */
+                if (opened_image_fd >= 0) {
+                        safe_close(setup->image_fd);
+                        setup->image_fd = TAKE_FD(opened_image_fd);
+                }
+
                 setup->do_offline_fallocate = !(setup->do_offline_fitrim = user_record_luks_offline_discard(h));
                 setup->do_mark_clean = marked_dirty;
         }
@@ -1294,11 +1397,11 @@ static void print_size_summary(uint64_t host_size, uint64_t encrypted_size, stru
 
 int home_activate_luks(
                 UserRecord *h,
+                HomeSetup *setup,
                 PasswordCache *cache,
                 UserRecord **ret_home) {
 
         _cleanup_(user_record_unrefp) UserRecord *new_home = NULL, *luks_home_record = NULL;
-        _cleanup_(home_setup_undo) HomeSetup setup = HOME_SETUP_INIT;
         uint64_t host_size, encrypted_size;
         const char *hdo, *hd;
         struct statfs sfs;
@@ -1306,6 +1409,7 @@ int home_activate_luks(
 
         assert(h);
         assert(user_record_storage(h) == USER_LUKS);
+        assert(setup);
         assert(ret_home);
 
         r = dlopen_cryptsetup();
@@ -1313,40 +1417,35 @@ int home_activate_luks(
                 return r;
 
         assert_se(hdo = user_record_home_directory(h));
-        hd = strdupa(hdo); /* copy the string out, since it might change later in the home record object */
+        hd = strdupa_safe(hdo); /* copy the string out, since it might change later in the home record object */
 
-        r = make_dm_names(h->user_name, &setup.dm_name, &setup.dm_node);
+        r = home_get_state_luks(h, setup);
         if (r < 0)
                 return r;
+        if (r > 0)
+                return log_error_errno(SYNTHETIC_ERRNO(EEXIST), "Device mapper device %s already exists, refusing.", setup->dm_node);
 
-        r = access(setup.dm_node, F_OK);
-        if (r < 0) {
-                if (errno != ENOENT)
-                        return log_error_errno(errno, "Failed to determine whether %s exists: %m", setup.dm_node);
-        } else
-                return log_error_errno(SYNTHETIC_ERRNO(EEXIST), "Device mapper device %s already exists, refusing.", setup.dm_node);
-
-        r = home_prepare_luks(
+        r = home_setup_luks(
                         h,
-                        false,
+                        0,
                         NULL,
                         cache,
-                        &setup,
+                        setup,
                         &luks_home_record);
         if (r < 0)
                 return r;
 
-        r = block_get_size_by_fd(setup.loop->fd, &host_size);
+        r = block_get_size_by_fd(setup->loop->fd, &host_size);
         if (r < 0)
                 return log_error_errno(r, "Failed to get loopback block device size: %m");
 
-        r = block_get_size_by_path(setup.dm_node, &encrypted_size);
+        r = block_get_size_by_path(setup->dm_node, &encrypted_size);
         if (r < 0)
                 return log_error_errno(r, "Failed to get LUKS block device size: %m");
 
         r = home_refresh(
                         h,
-                        &setup,
+                        setup,
                         luks_home_record,
                         cache,
                         &sfs,
@@ -1354,28 +1453,28 @@ int home_activate_luks(
         if (r < 0)
                 return r;
 
-        r = home_extend_embedded_identity(new_home, h, &setup);
+        r = home_extend_embedded_identity(new_home, h, setup);
         if (r < 0)
                 return r;
 
-        setup.root_fd = safe_close(setup.root_fd);
+        setup->root_fd = safe_close(setup->root_fd);
 
         r = home_move_mount(user_record_user_name_and_realm(h), hd);
         if (r < 0)
                 return r;
 
-        setup.undo_mount = false;
-        setup.do_offline_fitrim = false;
+        setup->undo_mount = false;
+        setup->do_offline_fitrim = false;
 
-        loop_device_relinquish(setup.loop);
+        loop_device_relinquish(setup->loop);
 
-        r = sym_crypt_deactivate_by_name(NULL, setup.dm_name, CRYPT_DEACTIVATE_DEFERRED);
+        r = sym_crypt_deactivate_by_name(NULL, setup->dm_name, CRYPT_DEACTIVATE_DEFERRED);
         if (r < 0)
                 log_warning_errno(r, "Failed to relinquish DM device, ignoring: %m");
 
-        setup.undo_dm = false;
-        setup.do_offline_fallocate = false;
-        setup.do_mark_clean = false;
+        setup->undo_dm = false;
+        setup->do_offline_fallocate = false;
+        setup->do_mark_clean = false;
 
         log_info("Everything completed.");
 
@@ -1555,8 +1654,7 @@ static int luks_format(
 
         STRV_FOREACH(pp, effective_passwords) {
 
-                if (strv_contains(cache->pkcs11_passwords, *pp) ||
-                    strv_contains(cache->fido2_passwords, *pp)) {
+                if (password_cache_contains(cache, *pp)) { /* is this a fido2 or pkcs11 password? */
                         log_debug("Using minimal PBKDF for slot %i", slot);
                         r = sym_crypt_set_pbkdf_type(cd, &minimal_pbkdf);
                 } else {
@@ -1893,7 +1991,7 @@ static int home_truncate(
 
 int home_create_luks(
                 UserRecord *h,
-                PasswordCache *cache,
+                const PasswordCache *cache,
                 char **effective_passwords,
                 UserRecord **ret_home) {
 
@@ -2287,7 +2385,7 @@ fail:
         return r;
 }
 
-int home_validate_update_luks(UserRecord *h, HomeSetup *setup) {
+int home_get_state_luks(UserRecord *h, HomeSetup *setup) {
         _cleanup_free_ char *dm_name = NULL, *dm_node = NULL;
         int r;
 
@@ -2642,7 +2740,7 @@ static int apply_resize_partition(int fd, sd_id128_t disk_uuids, struct fdisk_ta
 
 int home_resize_luks(
                 UserRecord *h,
-                bool already_activated,
+                HomeSetupFlags flags,
                 PasswordCache *cache,
                 HomeSetup *setup,
                 UserRecord **ret_home) {
@@ -2650,13 +2748,13 @@ int home_resize_luks(
         uint64_t old_image_size, new_image_size, old_fs_size, new_fs_size, crypto_offset, new_partition_size;
         _cleanup_(user_record_unrefp) UserRecord *header_home = NULL, *embedded_home = NULL, *new_home = NULL;
         _cleanup_(fdisk_unref_tablep) struct fdisk_table *table = NULL;
+        _cleanup_close_ int opened_image_fd = -1;
         _cleanup_free_ char *whole_disk = NULL;
-        _cleanup_close_ int image_fd = -1;
+        int r, resize_type, image_fd = -1;
         sd_id128_t disk_uuid;
         const char *ip, *ipo;
         struct statfs sfs;
         struct stat st;
-        int r, resize_type;
 
         assert(h);
         assert(user_record_storage(h) == USER_LUKS);
@@ -2668,14 +2766,19 @@ int home_resize_luks(
                 return r;
 
         assert_se(ipo = user_record_image_path(h));
-        ip = strdupa(ipo); /* copy out since original might change later in home record object */
+        ip = strdupa_safe(ipo); /* copy out since original might change later in home record object */
 
-        image_fd = open(ip, O_RDWR|O_CLOEXEC|O_NOCTTY|O_NONBLOCK);
-        if (image_fd < 0)
-                return log_error_errno(errno, "Failed to open image file %s: %m", ip);
+        if (setup->image_fd < 0) {
+                setup->image_fd = open_image_file(h, NULL, &st);
+                if (setup->image_fd < 0)
+                        return setup->image_fd;
+        } else {
+                if (fstat(setup->image_fd, &st) < 0)
+                        return log_error_errno(errno, "Failed to stat image file %s: %m", ip);
+        }
+
+        image_fd = setup->image_fd;
 
-        if (fstat(image_fd, &st) < 0)
-                return log_error_errno(errno, "Failed to stat image file %s: %m", ip);
         if (S_ISBLK(st.st_mode)) {
                 dev_t parent;
 
@@ -2693,12 +2796,12 @@ int home_resize_luks(
                         if (r < 0)
                                 return log_error_errno(r, "Failed to derive whole disk path for %s: %m", ip);
 
-                        safe_close(image_fd);
-
-                        image_fd = open(whole_disk, O_RDWR|O_CLOEXEC|O_NOCTTY|O_NONBLOCK);
-                        if (image_fd < 0)
+                        opened_image_fd = open(whole_disk, O_RDWR|O_CLOEXEC|O_NOCTTY|O_NONBLOCK);
+                        if (opened_image_fd < 0)
                                 return log_error_errno(errno, "Failed to open whole block device %s: %m", whole_disk);
 
+                        image_fd = opened_image_fd;
+
                         if (fstat(image_fd, &st) < 0)
                                 return log_error_errno(errno, "Failed to stat whole block device %s: %m", whole_disk);
                         if (!S_ISBLK(st.st_mode))
@@ -2738,7 +2841,7 @@ int home_resize_luks(
                 new_image_size = new_image_size_rounded;
         }
 
-        r = home_prepare_luks(h, already_activated, whole_disk, cache, setup, &header_home);
+        r = home_setup_luks(h, flags, whole_disk, cache, setup, &header_home);
         if (r < 0)
                 return r;
 
@@ -2793,7 +2896,7 @@ int home_resize_luks(
         resize_type = can_resize_fs(setup->root_fd, old_fs_size, new_fs_size);
         if (resize_type < 0)
                 return resize_type;
-        if (resize_type == CAN_RESIZE_OFFLINE && already_activated)
+        if (resize_type == CAN_RESIZE_OFFLINE && FLAGS_SET(flags, HOME_SETUP_ALREADY_ACTIVATED))
                 return log_error_errno(SYNTHETIC_ERRNO(ETXTBSY), "File systems of this type can only be resized offline, but is currently online.");
 
         log_info("Ready to resize image size %s â†’ %s, partition size %s â†’ %s, file system size %s â†’ %s.",
@@ -2840,7 +2943,7 @@ int home_resize_luks(
                 if (r > 0)
                         log_info("Growing of partition completed.");
 
-                if (ioctl(image_fd, BLKRRPART, 0) < 0)
+                if (S_ISBLK(st.st_mode) && ioctl(image_fd, BLKRRPART, 0) < 0)
                         log_debug_errno(errno, "BLKRRPART failed on block device, ignoring: %m");
 
                 /* Tell LUKS about the new bigger size too */
@@ -2868,12 +2971,15 @@ int home_resize_luks(
         }
 
         /* Now resize the file system */
-        if (resize_type == CAN_RESIZE_ONLINE)
+        if (resize_type == CAN_RESIZE_ONLINE) {
                 r = resize_fs(setup->root_fd, new_fs_size, NULL);
-        else
+                if (r < 0)
+                        return log_error_errno(r, "Failed to resize file system: %m");
+        } else {
                 r = ext4_offline_resize_fs(setup, new_fs_size, user_record_luks_discard(h), user_record_mount_flags(h));
-        if (r < 0)
-                return log_error_errno(r, "Failed to resize file system: %m");
+                if (r < 0)
+                        return r;
+        }
 
         log_info("File system resizing completed.");
 
@@ -2914,7 +3020,7 @@ int home_resize_luks(
                 if (r > 0)
                         log_info("Shrinking of partition completed.");
 
-                if (ioctl(image_fd, BLKRRPART, 0) < 0)
+                if (S_ISBLK(st.st_mode) && ioctl(image_fd, BLKRRPART, 0) < 0)
                         log_debug_errno(errno, "BLKRRPART failed on block device, ignoring: %m");
         } else {
                 r = home_store_embedded_identity(new_home, setup->root_fd, h->uid, embedded_home);
@@ -2937,7 +3043,7 @@ int home_resize_luks(
         if (r < 0)
                 return r;
 
-        r = home_setup_undo(setup);
+        r = home_setup_done(setup);
         if (r < 0)
                 return r;
 
@@ -2952,7 +3058,7 @@ int home_resize_luks(
 int home_passwd_luks(
                 UserRecord *h,
                 HomeSetup *setup,
-                PasswordCache *cache,      /* the passwords acquired via PKCS#11/FIDO2 security tokens */
+                const PasswordCache *cache,      /* the passwords acquired via PKCS#11/FIDO2 security tokens */
                 char **effective_passwords /* new passwords */) {
 
         size_t volume_key_size, max_key_slots, n_effective;
@@ -2989,7 +3095,11 @@ int home_passwd_luks(
                 return log_oom();
 
         r = -ENOKEY;
-        FOREACH_POINTER(list, cache->pkcs11_passwords, cache->fido2_passwords, h->password) {
+        FOREACH_POINTER(list,
+                        cache ? cache->pkcs11_passwords : NULL,
+                        cache ? cache->fido2_passwords : NULL,
+                        h->password) {
+
                 r = luks_try_passwords(setup->crypt_device, list, volume_key, &volume_key_size);
                 if (r != -ENOKEY)
                         break;
@@ -3015,8 +3125,7 @@ int home_passwd_luks(
                         continue;
                 }
 
-                if (strv_contains(cache->pkcs11_passwords, effective_passwords[i]) ||
-                    strv_contains(cache->fido2_passwords, effective_passwords[i])) {
+                if (password_cache_contains(cache, effective_passwords[i])) { /* Is this a FIDO2 or PKCS#11 password? */
                         log_debug("Using minimal PBKDF for slot %zu", i);
                         r = sym_crypt_set_pbkdf_type(setup->crypt_device, &minimal_pbkdf);
                 } else {
@@ -3117,7 +3226,7 @@ static int luks_try_resume(
         return -ENOKEY;
 }
 
-int home_unlock_luks(UserRecord *h, PasswordCache *cache) {
+int home_unlock_luks(UserRecord *h, const PasswordCache *cache) {
         _cleanup_free_ char *dm_name = NULL, *dm_node = NULL;
         _cleanup_(sym_crypt_freep) struct crypt_device *cd = NULL;
         char **list;
@@ -3141,7 +3250,10 @@ int home_unlock_luks(UserRecord *h, PasswordCache *cache) {
         cryptsetup_enable_logging(cd);
 
         r = -ENOKEY;
-        FOREACH_POINTER(list, cache->pkcs11_passwords, cache->fido2_passwords, h->password) {
+        FOREACH_POINTER(list,
+                        cache ? cache->pkcs11_passwords : NULL,
+                        cache ? cache->fido2_passwords : NULL,
+                        h->password) {
                 r = luks_try_resume(cd, dm_name, list);
                 if (r != -ENOKEY)
                         break;
index 8764862bd2cb47821bdb3b07adb166c95874e6aa..f8d22bb647a0ae44bcf1266d92703b8f7b66b151 100644 (file)
@@ -5,24 +5,24 @@
 #include "homework.h"
 #include "user-record.h"
 
-int home_prepare_luks(UserRecord *h, bool already_activated, const char *force_image_path, PasswordCache *cache, HomeSetup *setup, UserRecord **ret_luks_home);
+int home_setup_luks(UserRecord *h, HomeSetupFlags flags, const char *force_image_path, PasswordCache *cache, HomeSetup *setup, UserRecord **ret_luks_home);
 
-int home_activate_luks(UserRecord *h, PasswordCache *cache, UserRecord **ret_home);
+int home_activate_luks(UserRecord *h, HomeSetup *setup, PasswordCache *cache, UserRecord **ret_home);
 int home_deactivate_luks(UserRecord *h);
 int home_trim_luks(UserRecord *h);
 
 int home_store_header_identity_luks(UserRecord *h, HomeSetup *setup, UserRecord *old_home);
 
-int home_create_luks(UserRecord *h, PasswordCache *cache, char **effective_passwords, UserRecord **ret_home);
+int home_create_luks(UserRecord *h, const PasswordCache *cache, char **effective_passwords, UserRecord **ret_home);
 
-int home_validate_update_luks(UserRecord *h, HomeSetup *setup);
+int home_get_state_luks(UserRecord *h, HomeSetup *setup);
 
-int home_resize_luks(UserRecord *h, bool already_activated, PasswordCache *cache, HomeSetup *setup, UserRecord **ret_home);
+int home_resize_luks(UserRecord *h, HomeSetupFlags flags, PasswordCache *cache, HomeSetup *setup, UserRecord **ret_home);
 
-int home_passwd_luks(UserRecord *h, HomeSetup *setup, PasswordCache *cache, char **effective_passwords);
+int home_passwd_luks(UserRecord *h, HomeSetup *setup, const PasswordCache *cache, char **effective_passwords);
 
 int home_lock_luks(UserRecord *h);
-int home_unlock_luks(UserRecord *h, PasswordCache *cache);
+int home_unlock_luks(UserRecord *h, const PasswordCache *cache);
 
 static inline uint64_t luks_volume_key_size_convert(struct crypt_device *cd) {
         int k;
index ee1d4068bad92779eadd5ee3ade372b66da5eb96..78ca979fae3fdc481ad7b3f2c4175e5734454e2a 100644 (file)
@@ -28,6 +28,7 @@
 #include "rm-rf.h"
 #include "stat-util.h"
 #include "strv.h"
+#include "sync-util.h"
 #include "tmpfile-util.h"
 #include "user-util.h"
 #include "virt.h"
@@ -283,7 +284,21 @@ int user_record_authenticate(
         return 0;
 }
 
-int home_setup_undo(HomeSetup *setup) {
+static void drop_caches_now(void) {
+        int r;
+
+        /* Drop file system caches now. See https://www.kernel.org/doc/Documentation/sysctl/vm.txt for
+         * details. We write "2" into /proc/sys/vm/drop_caches to ensure dentries/inodes are flushed, but not
+         * more. */
+
+        r = write_string_file("/proc/sys/vm/drop_caches", "2\n", WRITE_STRING_FILE_DISABLE_BUFFER);
+        if (r < 0)
+                log_warning_errno(r, "Failed to drop caches, ignoring: %m");
+        else
+                log_debug("Dropped caches.");
+}
+
+int home_setup_done(HomeSetup *setup) {
         int r = 0, q;
 
         assert(setup);
@@ -295,6 +310,9 @@ int home_setup_undo(HomeSetup *setup) {
                                 r = q;
                 }
 
+                if (syncfs(setup->root_fd) < 0)
+                        log_debug_errno(errno, "Failed to synchronize home directory, ignoring: %m");
+
                 setup->root_fd = safe_close(setup->root_fd);
         }
 
@@ -341,16 +359,18 @@ int home_setup_undo(HomeSetup *setup) {
                 setup->crypt_device = NULL;
         }
 
-        explicit_bzero_safe(setup->volume_key, setup->volume_key_size);
-        setup->volume_key = mfree(setup->volume_key);
+        setup->volume_key = erase_and_free(setup->volume_key);
         setup->volume_key_size = 0;
 
+        if (setup->do_drop_caches)
+                drop_caches_now();
+
         return r;
 }
 
-int home_prepare(
+int home_setup(
                 UserRecord *h,
-                bool already_activated,
+                HomeSetupFlags flags,
                 PasswordCache *cache,
                 HomeSetup *setup,
                 UserRecord **ret_header_home) {
@@ -367,22 +387,25 @@ int home_prepare(
 
         /* Makes a home directory accessible (through the root_fd file descriptor, not by path!). */
 
+        if (!FLAGS_SET(flags, HOME_SETUP_ALREADY_ACTIVATED)) /* If we set up the directory, we should also drop caches once we are done */
+                setup->do_drop_caches = setup->do_drop_caches || user_record_drop_caches(h);
+
         switch (user_record_storage(h)) {
 
         case USER_LUKS:
-                return home_prepare_luks(h, already_activated, NULL, cache, setup, ret_header_home);
+                return home_setup_luks(h, flags, NULL, cache, setup, ret_header_home);
 
         case USER_SUBVOLUME:
         case USER_DIRECTORY:
-                r = home_prepare_directory(h, already_activated, setup);
+                r = home_setup_directory(h, setup);
                 break;
 
         case USER_FSCRYPT:
-                r = home_prepare_fscrypt(h, already_activated, cache, setup);
+                r = home_setup_fscrypt(h, cache, setup);
                 break;
 
         case USER_CIFS:
-                r = home_prepare_cifs(h, already_activated, setup);
+                r = home_setup_cifs(h, flags, setup);
                 break;
 
         default:
@@ -736,8 +759,9 @@ int home_refresh(
 }
 
 static int home_activate(UserRecord *h, UserRecord **ret_home) {
-        _cleanup_(password_cache_free) PasswordCache cache = {};
+        _cleanup_(home_setup_done) HomeSetup setup = HOME_SETUP_INIT;
         _cleanup_(user_record_unrefp) UserRecord *new_home = NULL;
+        _cleanup_(password_cache_free) PasswordCache cache = {};
         int r;
 
         assert(h);
@@ -768,7 +792,7 @@ static int home_activate(UserRecord *h, UserRecord **ret_home) {
         switch (user_record_storage(h)) {
 
         case USER_LUKS:
-                r = home_activate_luks(h, &cache, &new_home);
+                r = home_activate_luks(h, &setup, &cache, &new_home);
                 if (r < 0)
                         return r;
 
@@ -777,14 +801,14 @@ static int home_activate(UserRecord *h, UserRecord **ret_home) {
         case USER_SUBVOLUME:
         case USER_DIRECTORY:
         case USER_FSCRYPT:
-                r = home_activate_directory(h, &cache, &new_home);
+                r = home_activate_directory(h, &setup, &cache, &new_home);
                 if (r < 0)
                         return r;
 
                 break;
 
         case USER_CIFS:
-                r = home_activate_cifs(h, &cache, &new_home);
+                r = home_activate_cifs(h, &setup, &cache, &new_home);
                 if (r < 0)
                         return r;
 
@@ -827,6 +851,13 @@ static int home_deactivate(UserRecord *h, bool force) {
                                 return r;
                 }
 
+                /* Sync explicitly, so that the drop caches logic below can work as documented */
+                r = syncfs_path(AT_FDCWD, user_record_home_directory(h));
+                if (r < 0)
+                        log_debug_errno(r, "Failed to synchronize home directory, ignoring: %m");
+                else
+                        log_info("Syncing completed.");
+
                 if (umount2(user_record_home_directory(h), UMOUNT_NOFOLLOW | (force ? MNT_FORCE|MNT_DETACH : 0)) < 0)
                         return log_error_errno(errno, "Failed to unmount %s: %m", user_record_home_directory(h));
 
@@ -846,6 +877,9 @@ static int home_deactivate(UserRecord *h, bool force) {
         if (!done)
                 return log_error_errno(SYNTHETIC_ERRNO(ENOEXEC), "Home is not active.");
 
+        if (user_record_drop_caches(h))
+                drop_caches_now();
+
         log_info("Everything completed.");
         return 0;
 }
@@ -1095,12 +1129,12 @@ static int determine_default_storage(UserStorage *ret) {
         if (r < 0)
                 return log_error_errno(r, "Failed to determine whether we are in a container: %m");
         if (r == 0) {
-                r = path_is_encrypted("/home");
+                r = path_is_encrypted(get_home_root());
                 if (r > 0)
-                        log_info("/home is encrypted, not using '%s' storage, in order to avoid double encryption.", user_storage_to_string(USER_LUKS));
+                        log_info("%s is encrypted, not using '%s' storage, in order to avoid double encryption.", get_home_root(), user_storage_to_string(USER_LUKS));
                 else {
                         if (r < 0)
-                                log_warning_errno(r, "Failed to determine if /home is encrypted, ignoring: %m");
+                                log_warning_errno(r, "Failed to determine if %s is encrypted, ignoring: %m", get_home_root());
 
                         r = dlopen_cryptsetup();
                         if (r < 0)
@@ -1114,14 +1148,14 @@ static int determine_default_storage(UserStorage *ret) {
         } else
                 log_info("Running in container, not using '%s' storage.", user_storage_to_string(USER_LUKS));
 
-        r = path_is_fs_type("/home", BTRFS_SUPER_MAGIC);
+        r = path_is_fs_type(get_home_root(), BTRFS_SUPER_MAGIC);
         if (r < 0)
-                log_warning_errno(r, "Failed to determine file system of /home, ignoring: %m");
+                log_warning_errno(r, "Failed to determine file system of %s, ignoring: %m", get_home_root());
         if (r > 0) {
-                log_info("/home is on btrfs, using '%s' as storage.", user_storage_to_string(USER_SUBVOLUME));
+                log_info("%s is on btrfs, using '%s' as storage.", get_home_root(), user_storage_to_string(USER_SUBVOLUME));
                 *ret = USER_SUBVOLUME;
         } else {
-                log_info("/home is on simple file system, using '%s' as storage.", user_storage_to_string(USER_DIRECTORY));
+                log_info("%s is on simple file system, using '%s' as storage.", get_home_root(), user_storage_to_string(USER_DIRECTORY));
                 *ret = USER_DIRECTORY;
         }
 
@@ -1130,6 +1164,7 @@ static int determine_default_storage(UserStorage *ret) {
 
 static int home_create(UserRecord *h, UserRecord **ret_home) {
         _cleanup_(strv_free_erasep) char **effective_passwords = NULL;
+        _cleanup_(home_setup_done) HomeSetup setup = HOME_SETUP_INIT;
         _cleanup_(user_record_unrefp) UserRecord *new_home = NULL;
         _cleanup_(password_cache_free) PasswordCache cache = {};
         UserStorage new_storage = _USER_STORAGE_INVALID;
@@ -1205,7 +1240,7 @@ static int home_create(UserRecord *h, UserRecord **ret_home) {
                 break;
 
         case USER_CIFS:
-                r = home_create_cifs(h, &new_home);
+                r = home_create_cifs(h, &setup, &new_home);
                 break;
 
         default:
@@ -1268,9 +1303,21 @@ static int home_remove(UserRecord *h) {
                                 if (unlink(ip) < 0) {
                                         if (errno != ENOENT)
                                                 return log_error_errno(errno, "Failed to remove %s: %m", ip);
-                                } else
+                                } else {
+                                        _cleanup_free_ char *parent = NULL;
+
                                         deleted = true;
 
+                                        r = path_extract_directory(ip, &parent);
+                                        if (r < 0)
+                                                log_debug_errno(r, "Failed to determine parent directory of '%s': %m", ip);
+                                        else {
+                                                r = fsync_path_at(AT_FDCWD, parent);
+                                                if (r < 0)
+                                                        log_debug_errno(r, "Failed to synchronize disk after deleting '%s', ignoring: %m", ip);
+                                        }
+                                }
+
                         } else if (S_ISBLK(st.st_mode))
                                 log_info("Not removing file system on block device %s.", ip);
                         else
@@ -1285,7 +1332,7 @@ static int home_remove(UserRecord *h) {
         case USER_FSCRYPT:
                 assert(ip);
 
-                r = rm_rf(ip, REMOVE_ROOT|REMOVE_PHYSICAL|REMOVE_SUBVOLUME);
+                r = rm_rf(ip, REMOVE_ROOT|REMOVE_PHYSICAL|REMOVE_SUBVOLUME|REMOVE_SYNCFS);
                 if (r < 0) {
                         if (r != -ENOENT)
                                 return log_warning_errno(r, "Failed to remove %s: %m", ip);
@@ -1316,16 +1363,19 @@ static int home_remove(UserRecord *h) {
                         deleted = true;
         }
 
-        if (deleted)
+        if (deleted) {
+                if (user_record_drop_caches(h))
+                        drop_caches_now();
+
                 log_info("Everything completed.");
-        else
+        else
                 return log_notice_errno(SYNTHETIC_ERRNO(EALREADY),
                                         "Nothing to remove.");
 
         return 0;
 }
 
-static int home_validate_update(UserRecord *h, HomeSetup *setup) {
+static int home_validate_update(UserRecord *h, HomeSetup *setup, HomeSetupFlags *flags) {
         bool has_mount = false;
         int r;
 
@@ -1360,7 +1410,7 @@ static int home_validate_update(UserRecord *h, HomeSetup *setup) {
                 break;
 
         case USER_LUKS: {
-                r = home_validate_update_luks(h, setup);
+                r = home_get_state_luks(h, setup);
                 if (r < 0)
                         return r;
                 if ((r > 0) != has_mount)
@@ -1373,14 +1423,17 @@ static int home_validate_update(UserRecord *h, HomeSetup *setup) {
                 assert_not_reached();
         }
 
+        if (flags)
+                SET_FLAG(*flags, HOME_SETUP_ALREADY_ACTIVATED, has_mount);
+
         return has_mount; /* return true if the home record is already active */
 }
 
 static int home_update(UserRecord *h, UserRecord **ret) {
         _cleanup_(user_record_unrefp) UserRecord *new_home = NULL, *header_home = NULL, *embedded_home = NULL;
-        _cleanup_(home_setup_undo) HomeSetup setup = HOME_SETUP_INIT;
+        _cleanup_(home_setup_done) HomeSetup setup = HOME_SETUP_INIT;
         _cleanup_(password_cache_free) PasswordCache cache = {};
-        bool already_activated = false;
+        HomeSetupFlags flags = 0;
         int r;
 
         assert(h);
@@ -1391,13 +1444,11 @@ static int home_update(UserRecord *h, UserRecord **ret) {
                 return r;
         assert(r > 0); /* Insist that a password was verified */
 
-        r = home_validate_update(h, &setup);
+        r = home_validate_update(h, &setup, &flags);
         if (r < 0)
                 return r;
 
-        already_activated = r > 0;
-
-        r = home_prepare(h, already_activated, &cache, &setup, &header_home);
+        r = home_setup(h, flags, &cache, &setup, &header_home);
         if (r < 0)
                 return r;
 
@@ -1421,7 +1472,7 @@ static int home_update(UserRecord *h, UserRecord **ret) {
         if (r < 0)
                 return r;
 
-        r = home_setup_undo(&setup);
+        r = home_setup_done(&setup);
         if (r < 0)
                 return r;
 
@@ -1432,9 +1483,9 @@ static int home_update(UserRecord *h, UserRecord **ret) {
 }
 
 static int home_resize(UserRecord *h, UserRecord **ret) {
-        _cleanup_(home_setup_undo) HomeSetup setup = HOME_SETUP_INIT;
+        _cleanup_(home_setup_done) HomeSetup setup = HOME_SETUP_INIT;
         _cleanup_(password_cache_free) PasswordCache cache = {};
-        bool already_activated = false;
+        HomeSetupFlags flags = 0;
         int r;
 
         assert(h);
@@ -1448,21 +1499,19 @@ static int home_resize(UserRecord *h, UserRecord **ret) {
                 return r;
         assert(r > 0); /* Insist that a password was verified */
 
-        r = home_validate_update(h, &setup);
+        r = home_validate_update(h, &setup, &flags);
         if (r < 0)
                 return r;
 
-        already_activated = r > 0;
-
         switch (user_record_storage(h)) {
 
         case USER_LUKS:
-                return home_resize_luks(h, already_activated, &cache, &setup, ret);
+                return home_resize_luks(h, flags, &cache, &setup, ret);
 
         case USER_DIRECTORY:
         case USER_SUBVOLUME:
         case USER_FSCRYPT:
-                return home_resize_directory(h, already_activated, &cache, &setup, ret);
+                return home_resize_directory(h, flags, &cache, &setup, ret);
 
         default:
                 return log_error_errno(SYNTHETIC_ERRNO(ENOTTY), "Resizing home directories of type '%s' currently not supported.", user_storage_to_string(user_record_storage(h)));
@@ -1472,9 +1521,9 @@ static int home_resize(UserRecord *h, UserRecord **ret) {
 static int home_passwd(UserRecord *h, UserRecord **ret_home) {
         _cleanup_(user_record_unrefp) UserRecord *header_home = NULL, *embedded_home = NULL, *new_home = NULL;
         _cleanup_(strv_free_erasep) char **effective_passwords = NULL;
-        _cleanup_(home_setup_undo) HomeSetup setup = HOME_SETUP_INIT;
+        _cleanup_(home_setup_done) HomeSetup setup = HOME_SETUP_INIT;
         _cleanup_(password_cache_free) PasswordCache cache = {};
-        bool already_activated = false;
+        HomeSetupFlags flags = 0;
         int r;
 
         assert(h);
@@ -1487,13 +1536,11 @@ static int home_passwd(UserRecord *h, UserRecord **ret_home) {
         if (r < 0)
                 return r;
 
-        r = home_validate_update(h, &setup);
+        r = home_validate_update(h, &setup, &flags);
         if (r < 0)
                 return r;
 
-        already_activated = r > 0;
-
-        r = home_prepare(h, already_activated, &cache, &setup, &header_home);
+        r = home_setup(h, flags, &cache, &setup, &header_home);
         if (r < 0)
                 return r;
 
@@ -1535,7 +1582,7 @@ static int home_passwd(UserRecord *h, UserRecord **ret_home) {
         if (r < 0)
                 return r;
 
-        r = home_setup_undo(&setup);
+        r = home_setup_done(&setup);
         if (r < 0)
                 return r;
 
@@ -1547,9 +1594,9 @@ static int home_passwd(UserRecord *h, UserRecord **ret_home) {
 
 static int home_inspect(UserRecord *h, UserRecord **ret_home) {
         _cleanup_(user_record_unrefp) UserRecord *header_home = NULL, *new_home = NULL;
-        _cleanup_(home_setup_undo) HomeSetup setup = HOME_SETUP_INIT;
+        _cleanup_(home_setup_done) HomeSetup setup = HOME_SETUP_INIT;
         _cleanup_(password_cache_free) PasswordCache cache = {};
-        bool already_activated = false;
+        HomeSetupFlags flags = 0;
         int r;
 
         assert(h);
@@ -1559,13 +1606,11 @@ static int home_inspect(UserRecord *h, UserRecord **ret_home) {
         if (r < 0)
                 return r;
 
-        r = home_validate_update(h, &setup);
+        r = home_validate_update(h, &setup, &flags);
         if (r < 0)
                 return r;
 
-        already_activated = r > 0;
-
-        r = home_prepare(h, already_activated, &cache, &setup, &header_home);
+        r = home_setup(h, flags, &cache, &setup, &header_home);
         if (r < 0)
                 return r;
 
@@ -1577,7 +1622,7 @@ static int home_inspect(UserRecord *h, UserRecord **ret_home) {
         if (r < 0)
                 return r;
 
-        r = home_setup_undo(&setup);
+        r = home_setup_done(&setup);
         if (r < 0)
                 return r;
 
@@ -1706,6 +1751,7 @@ static int run(int argc, char *argv[]) {
          * ENOEXEC         â†’ file system is currently not active
          * ENOSPC          â†’ not enough disk space for operation
          * EKEYREVOKED     â†’ user record has not suitable hashed password or pkcs#11 entry, we cannot authenticate
+         * EADDRINUSE      â†’ home image is already used elsewhere (lock taken)
          */
 
         if (streq(argv[1], "activate"))
index fb53fd49b0376d9fc77718caea8c59739d7a44f2..5fa4b653e2b9dac828964229b47ab67cb816e8c6 100644 (file)
@@ -7,6 +7,7 @@
 #include "sd-id128.h"
 
 #include "loop-util.h"
+#include "strv.h"
 #include "user-record.h"
 #include "user-record-util.h"
 
@@ -32,19 +33,28 @@ typedef struct HomeSetup {
         bool do_offline_fitrim;
         bool do_offline_fallocate;
         bool do_mark_clean;
+        bool do_drop_caches;
 
         uint64_t partition_offset;
         uint64_t partition_size;
 } HomeSetup;
 
 typedef struct PasswordCache {
-        /* Decoding passwords from security tokens is expensive and typically requires user interaction, hence cache any we already figured out. */
+        /* Decoding passwords from security tokens is expensive and typically requires user interaction,
+         * hence cache any we already figured out. */
         char **pkcs11_passwords;
         char **fido2_passwords;
 } PasswordCache;
 
 void password_cache_free(PasswordCache *cache);
 
+static inline bool password_cache_contains(const PasswordCache *cache, const char *p) {
+        if (!cache)
+                return false;
+
+        return strv_contains(cache->pkcs11_passwords, p) || strv_contains(cache->fido2_passwords, p);
+}
+
 #define HOME_SETUP_INIT                                 \
         {                                               \
                 .root_fd = -1,                          \
@@ -53,9 +63,14 @@ void password_cache_free(PasswordCache *cache);
                 .partition_size = UINT64_MAX,           \
         }
 
-int home_setup_undo(HomeSetup *setup);
+/* Various flags for the operation of setting up a home directory */
+typedef enum HomeSetupFlags {
+        HOME_SETUP_ALREADY_ACTIVATED = 1 << 0, /* Open an already activated home, rather than activate it afresh */
+} HomeSetupFlags;
+
+int home_setup_done(HomeSetup *setup);
 
-int home_prepare(UserRecord *h, bool already_activated, PasswordCache *cache, HomeSetup *setup, UserRecord **ret_header_home);
+int home_setup(UserRecord *h, HomeSetupFlags flags, PasswordCache *cache, HomeSetup *setup, UserRecord **ret_header_home);
 
 int home_refresh(UserRecord *h, HomeSetup *setup, UserRecord *header_home, PasswordCache *cache, struct statfs *ret_statfs, UserRecord **ret_new_home);
 
index bc0c4171b4f38265a1bf1858e65d19806271d0e1..464f1dbb7a096377f92d2a8e80ad075f8982f59f 100644 (file)
@@ -75,7 +75,7 @@ int user_record_synthesize(
         if (!ip)
                 return -ENOMEM;
 
-        hd = path_join("/home/", user_name);
+        hd = path_join(get_home_root(), user_name);
         if (!hd)
                 return -ENOMEM;
 
diff --git a/src/integritysetup/integrity-util.c b/src/integritysetup/integrity-util.c
new file mode 100644 (file)
index 0000000..5970a13
--- /dev/null
@@ -0,0 +1,66 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+#include "integrity-util.h"
+
+#include "extract-word.h"
+#include "fileio.h"
+#include "path-util.h"
+#include "percent-util.h"
+
+
+static int supported_integrity_algorithm(char *user_supplied) {
+        if (!STR_IN_SET(user_supplied, "crc32", "crc32c", "sha1", "sha256", "hmac-sha256"))
+                return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Unsupported integrity algorithm (%s)", user_supplied);
+        return 0;
+}
+
+int parse_integrity_options(
+                const char *options,
+                uint32_t *ret_activate_flags,
+                int *ret_percent,
+                usec_t *ret_commit_time,
+                char **ret_data_device,
+                char **ret_integrity_alg) {
+        int r;
+
+        for (;;) {
+                _cleanup_free_ char *word = NULL;
+                char *val;
+
+                r = extract_first_word(&options, &word, ",", EXTRACT_DONT_COALESCE_SEPARATORS | EXTRACT_UNESCAPE_SEPARATORS);
+                if (r < 0)
+                        return log_error_errno(r, "Failed to parse options: %m");
+                if (r == 0)
+                        break;
+                else if (streq(word, "allow-discards")) {
+                        if (ret_activate_flags)
+                                *ret_activate_flags |= CRYPT_ACTIVATE_ALLOW_DISCARDS;
+                } else if ((val = startswith(word, "journal-watermark="))) {
+                        r = parse_percent(val);
+                        if (r < 0)
+                                return log_error_errno(r, "Failed to parse journal-watermark value or value out of range (%s)", val);
+                        if (ret_percent)
+                                *ret_percent = r;
+                } else if ((val = startswith(word, "journal-commit-time="))) {
+                        usec_t tmp_commit_time;
+                        r = parse_sec(val, &tmp_commit_time);
+                        if (r < 0)
+                                return log_error_errno(r, "Failed to parse journal-commit-time value (%s)", val);
+                        if (ret_commit_time)
+                                *ret_commit_time = tmp_commit_time;
+                } else if ((val = startswith(word, "data-device="))) {
+                        r = free_and_strdup(ret_data_device, val);
+                        if (r < 0)
+                                return log_oom();
+                } else if ((val = startswith(word, "integrity-algorithm="))) {
+                        r = free_and_strdup(ret_integrity_alg, val);
+                        if (r < 0)
+                                return log_oom();
+                        r = supported_integrity_algorithm(*ret_integrity_alg);
+                        if (r < 0)
+                                return r;
+                } else
+                        log_warning("Encountered unknown option '%s', ignoring.", word);
+        }
+
+        return r;
+}
diff --git a/src/integritysetup/integrity-util.h b/src/integritysetup/integrity-util.h
new file mode 100644 (file)
index 0000000..b27975c
--- /dev/null
@@ -0,0 +1,19 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+#pragma once
+
+#include <stdint.h>
+
+#include "cryptsetup-util.h"
+#include "time-util.h"
+
+
+int parse_integrity_options(
+                const char *options,
+                uint32_t *ret_activate_flags,
+                int *ret_percent,
+                usec_t *ret_commit_time,
+                char **ret_data_device,
+                char **ret_integrity_alg);
+
+#define DM_HMAC_256 "hmac(sha256)"
+#define DM_MAX_KEY_SIZE 4096            /* Maximum size of key allowed for dm-integrity */
diff --git a/src/integritysetup/integritysetup-generator.c b/src/integritysetup/integritysetup-generator.c
new file mode 100644 (file)
index 0000000..15f5089
--- /dev/null
@@ -0,0 +1,181 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+
+#include <errno.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include "alloc-util.h"
+#include "fd-util.h"
+#include "fileio.h"
+#include "fstab-util.h"
+#include "generator.h"
+#include "hexdecoct.h"
+#include "id128-util.h"
+#include "integrity-util.h"
+#include "main-func.h"
+#include "mkdir.h"
+#include "parse-util.h"
+#include "path-util.h"
+#include "proc-cmdline.h"
+#include "specifier.h"
+#include "string-util.h"
+#include "unit-name.h"
+
+static const char *arg_dest = NULL;
+static const char *arg_integritytab = NULL;
+static char *arg_options = NULL;
+STATIC_DESTRUCTOR_REGISTER(arg_options, freep);
+
+static int create_disk(
+                const char *name,
+                const char *device,
+                const char *key_file,
+                const char *options) {
+
+        _cleanup_free_ char *n = NULL, *dd = NULL, *e = NULL, *name_escaped = NULL, *key_file_escaped = NULL;
+        _cleanup_fclose_ FILE *f = NULL;
+        int r;
+        char *dmname = NULL;
+
+        assert(name);
+        assert(device);
+
+        name_escaped = specifier_escape(name);
+        if (!name_escaped)
+                return log_oom();
+
+        e = unit_name_escape(name);
+        if (!e)
+                return log_oom();
+
+        r = unit_name_build("systemd-integritysetup", e, ".service", &n);
+        if (r < 0)
+                return log_error_errno(r, "Failed to generate unit name: %m");
+
+        r = unit_name_from_path(device, ".device", &dd);
+        if (r < 0)
+                return log_error_errno(r, "Failed to generate unit name: %m");
+
+        r = generator_open_unit_file(arg_dest, NULL, n, &f);
+        if (r < 0)
+                return r;
+
+        if (key_file) {
+                if (!path_is_absolute(key_file))
+                        return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "key file not absolute file path %s", key_file);
+
+                key_file_escaped = specifier_escape(key_file);
+                if (!key_file_escaped)
+                        return log_oom();
+        }
+
+        if (options) {
+                r = parse_integrity_options(options, NULL, NULL, NULL, NULL, NULL);
+                if (r < 0)
+                        return r;
+        }
+
+        fprintf(f,
+                "[Unit]\n"
+                "Description=Integrity Setup for %%I\n"
+                "Documentation=man:integritytab(5) man:systemd-integritysetup-generator(8) man:systemd-integritysetup@.service(8)\n"
+                "SourcePath=%s\n"
+                "DefaultDependencies=no\n"
+                "IgnoreOnIsolate=true\n"
+                "After=integritysetup-pre.target systemd-udevd-kernel.socket\n"
+                "Before=blockdev@dev-mapper-%%i.target\n"
+                "Wants=blockdev@dev-mapper-%%i.target\n"
+                "Conflicts=umount.target\n"
+                "Before=integritysetup.target\n"
+                "BindsTo=%s\n"
+                "After=%s\n"
+                "Before=umount.target\n",
+                arg_integritytab,
+                dd, dd);
+
+        fprintf(f,
+                "\n"
+                "[Service]\n"
+                "Type=oneshot\n"
+                "RemainAfterExit=yes\n"
+                "TimeoutSec=0\n"
+                "ExecStart=" ROOTLIBEXECDIR "/systemd-integritysetup attach '%s' '%s' '%s' '%s'\n"
+                "ExecStop=" ROOTLIBEXECDIR "/systemd-integritysetup detach '%s'\n",
+                name_escaped, device, empty_to_dash(key_file_escaped), empty_to_dash(options),
+                name_escaped);
+
+        r = fflush_and_check(f);
+        if (r < 0)
+                return log_error_errno(r, "Failed to write unit file %s: %m", n);
+
+        r = generator_add_symlink(arg_dest, "integritysetup.target", "requires", n);
+        if (r < 0)
+                return r;
+
+        dmname = strjoina("dev-mapper-", e, ".device");
+        return generator_add_symlink(arg_dest, dmname, "requires", n);
+}
+
+static int add_integritytab_devices(void) {
+        _cleanup_fclose_ FILE *f = NULL;
+        unsigned integritytab_line = 0;
+        int r;
+
+        r = fopen_unlocked(arg_integritytab, "re", &f);
+        if (r < 0) {
+                if (errno != ENOENT)
+                        log_error_errno(errno, "Failed to open %s: %m", arg_integritytab);
+                return 0;
+        }
+
+        for (;;) {
+                _cleanup_free_ char *line = NULL, *name = NULL, *device_id = NULL, *device_path = NULL, *key_file = NULL, *options = NULL;
+                char *l;
+
+                r = read_line(f, LONG_LINE_MAX, &line);
+                if (r < 0)
+                        return log_error_errno(r, "Failed to read %s: %m", arg_integritytab);
+                if (r == 0)
+                        break;
+
+                integritytab_line++;
+
+                l = strstrip(line);
+                if (!l)
+                        continue;
+
+                if (IN_SET(l[0], 0, '#'))
+                        continue;
+
+                /* The key file and the options are optional */
+                r = sscanf(l, "%ms %ms %ms %ms", &name, &device_id, &key_file, &options);
+                if (!IN_SET(r, 2, 3, 4)) {
+                        log_error("Failed to parse %s:%u, ignoring.", l, integritytab_line);
+                        continue;
+                }
+
+                device_path = fstab_node_to_udev_node(device_id);
+                if (!device_path) {
+                        log_error("Failed to find device %s:%u, ignoring.", device_id, integritytab_line);
+                        continue;
+                }
+
+                r = create_disk(name, device_path, empty_or_dash_to_null(key_file), empty_or_dash_to_null(options));
+                if (r < 0)
+                        return r;
+        }
+
+        return 0;
+}
+
+static int run(const char *dest, const char *dest_early, const char *dest_late) {
+        assert_se(arg_dest = dest);
+
+        arg_integritytab = getenv("SYSTEMD_INTEGRITYTAB") ?: "/etc/integritytab";
+
+        return add_integritytab_devices();
+}
+
+DEFINE_MAIN_GENERATOR_FUNCTION(run);
diff --git a/src/integritysetup/integritysetup.c b/src/integritysetup/integritysetup.c
new file mode 100644 (file)
index 0000000..d8cfd12
--- /dev/null
@@ -0,0 +1,197 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+
+#include <errno.h>
+#include <stdio.h>
+#include <sys/stat.h>
+
+#include "alloc-util.h"
+#include "cryptsetup-util.h"
+#include "fileio.h"
+#include "hexdecoct.h"
+#include "integrity-util.h"
+#include "log.h"
+#include "main-func.h"
+#include "memory-util.h"
+#include "path-util.h"
+#include "parse-util.h"
+#include "pretty-print.h"
+#include "string-util.h"
+#include "terminal-util.h"
+
+static uint32_t arg_activate_flags;
+static int arg_percent;
+static usec_t arg_commit_time;
+static char *arg_existing_data_device;
+static char *arg_integrity_algorithm;
+
+STATIC_DESTRUCTOR_REGISTER(arg_existing_data_device, freep);
+STATIC_DESTRUCTOR_REGISTER(arg_integrity_algorithm, freep);
+
+static int help(void) {
+        _cleanup_free_ char *link = NULL;
+        int r;
+
+        r = terminal_urlify_man("systemd-integritysetup@.service", "8", &link);
+        if (r < 0)
+                return log_oom();
+
+        printf("%s attach VOLUME DEVICE [HMAC_KEY_FILE|-] [OPTIONS]\n"
+               "%s detach VOLUME\n\n"
+               "Attach or detach an integrity protected block device.\n"
+               "\nSee the %s for details.\n",
+               program_invocation_short_name,
+               program_invocation_short_name,
+               link);
+
+        return 0;
+}
+
+static int load_key_file(
+                const char *key_file,
+                void **ret_key_file_contents,
+                size_t *ret_key_file_size) {
+        int r;
+        _cleanup_(erase_and_freep) char *tmp_key_file_contents = NULL;
+        size_t tmp_key_file_size;
+
+        if (!path_is_absolute(key_file))
+                return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "key file not absolute path: %s", key_file);
+
+        r = read_full_file_full(
+                        AT_FDCWD, key_file, UINT64_MAX, DM_MAX_KEY_SIZE,
+                        READ_FULL_FILE_SECURE|READ_FULL_FILE_WARN_WORLD_READABLE|READ_FULL_FILE_CONNECT_SOCKET|READ_FULL_FILE_FAIL_WHEN_LARGER,
+                        NULL,
+                        &tmp_key_file_contents, &tmp_key_file_size);
+        if (r < 0)
+                return log_error_errno(r, "Failed to process key file: %m");
+
+        if (ret_key_file_contents && ret_key_file_size) {
+                *ret_key_file_contents = TAKE_PTR(tmp_key_file_contents);
+                *ret_key_file_size = tmp_key_file_size;
+        }
+
+        return 0;
+}
+
+static const char *integrity_algorithm_select(const void *key_file_buf) {
+        /*  To keep a bit of sanity for end users, the subset of integrity
+            algorithms we support will match what is used in integritysetup */
+        if (arg_integrity_algorithm) {
+                if (streq("hmac-sha256", arg_integrity_algorithm))
+                        return DM_HMAC_256;
+                return arg_integrity_algorithm;
+        } else if (key_file_buf)
+                return DM_HMAC_256;
+        return "crc32c";
+}
+
+static int run(int argc, char *argv[]) {
+        _cleanup_(crypt_freep) struct crypt_device *cd = NULL;
+        int r;
+        char *action, *volume;
+
+        if (argc <= 1 ||
+            strv_contains(strv_skip(argv, 1), "--help") ||
+            strv_contains(strv_skip(argv, 1), "-h") ||
+            streq(argv[1], "help"))
+                return help();
+
+        if (argc < 3)
+                return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "This program requires at least two arguments.");
+
+        action = argv[1];
+        volume = argv[2];
+
+        log_setup();
+
+        cryptsetup_enable_logging(NULL);
+
+        umask(0022);
+
+        if (streq(action, "attach")) {
+                /* attach name device optional_key_file optional_options */
+
+                crypt_status_info status;
+                _cleanup_(erase_and_freep) void *key_buf = NULL;
+                const char *device, *key_file, *options;
+                size_t key_buf_size = 0;
+
+                if (argc < 4)
+                        return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "attach requires at least three arguments.");
+
+                if (argc > 6)
+                        return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "attach has a maximum of five arguments.");
+
+                device = argv[3];
+                key_file = (argc > 4) ? empty_or_dash_to_null(argv[4]) : NULL;
+                options = (argc > 5) ? empty_or_dash_to_null(argv[5]) : NULL;
+
+                if (key_file) {
+                        r = load_key_file(key_file, &key_buf, &key_buf_size);
+                        if (r < 0)
+                                return r;
+                }
+
+                if (options) {
+                        r = parse_integrity_options(options, &arg_activate_flags, &arg_percent,
+                                                    &arg_commit_time, &arg_existing_data_device, &arg_integrity_algorithm);
+                        if (r < 0)
+                                return r;
+                }
+
+                r = crypt_init(&cd, device);
+                if (r < 0)
+                        return log_error_errno(r, "Failed to open integrity device %s: %m", device);
+
+                cryptsetup_enable_logging(cd);
+
+                status = crypt_status(cd, volume);
+                if (IN_SET(status, CRYPT_ACTIVE, CRYPT_BUSY)) {
+                        log_info("Volume %s already active.", volume);
+                        return 0;
+                }
+
+                if (!isempty(arg_existing_data_device)) {
+                        r = crypt_init_data_device(&cd, device, arg_existing_data_device);
+                        if (r < 0)
+                                return log_error_errno(r, "Failed to add separate data device: %m");
+                }
+
+                r = crypt_load(cd,
+                        CRYPT_INTEGRITY,
+                        &(struct crypt_params_integrity) {
+                                .journal_watermark = arg_percent,
+                                .journal_commit_time = DIV_ROUND_UP(arg_commit_time, USEC_PER_SEC),
+                                .integrity = integrity_algorithm_select(key_buf),
+                        });
+                if (r < 0)
+                        return log_error_errno(r, "Failed to load integrity superblock: %m");
+
+                r = crypt_activate_by_volume_key(cd, volume, key_buf, key_buf_size, arg_activate_flags);
+                if (r < 0)
+                        return log_error_errno(r, "Failed to set up integrity device: %m");
+
+        } else if (streq(action, "detach")) {
+
+                if (argc > 3)
+                        return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "detach has a maximum of two arguments.");
+
+                r = crypt_init_by_name(&cd, volume);
+                if (r == -ENODEV)
+                        return 0;
+                if (r < 0)
+                        return log_error_errno(r, "crypt_init_by_name() failed: %m");
+
+                cryptsetup_enable_logging(cd);
+
+                r = crypt_deactivate(cd, volume);
+                if (r < 0)
+                        return log_error_errno(r, "Failed to deactivate: %m");
+
+        } else
+                return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Unknown verb %s.", action);
+
+        return 0;
+}
+
+DEFINE_MAIN_FUNCTION(run);
index ba2a00da64acf18e7cd76fd4b329217f100c8990..91b28d0410ba005314deae1d4b1755c6edba3350 100644 (file)
@@ -662,7 +662,7 @@ static int create_remoteserver(
                         else
                                 url = strjoina(arg_url, "/entries");
                 } else
-                        url = strdupa(arg_url);
+                        url = strdupa_safe(arg_url);
 
                 log_info("Spawning curl %s...", url);
                 fd = spawn_curl(url);
@@ -673,7 +673,7 @@ static int create_remoteserver(
                 if (!hostname)
                         hostname = arg_url;
 
-                hostname = strndupa(hostname, strcspn(hostname, "/:"));
+                hostname = strndupa_safe(hostname, strcspn(hostname, "/:"));
 
                 r = journal_remote_add_source(s, fd, (char *) hostname, false);
                 if (r < 0)
index 1f756b4368cc5f125d906f93ee4c665e7679d9a6..fc52c546ed4dd012466d1652c2c88344f3a73b36 100644 (file)
@@ -439,7 +439,7 @@ static int setup_uploader(Uploader *u, const char *url, const char *state_file)
                 char *t;
                 size_t x;
 
-                t = strdupa(url);
+                t = strdupa_safe(url);
                 x = strlen(t);
                 while (x > 0 && t[x - 1] == '/')
                         t[x - 1] = '\0';
index 0eb27b88b295f22cfece988ef51c54527926f7e6..21e76a58992bc17781fdf52ff3fe7dc8dc5a1835 100644 (file)
@@ -280,7 +280,7 @@ static int parse_boot_descriptor(const char *x, sd_id128_t *boot_id, int *offset
         } else if (strlen(x) >= SD_ID128_STRING_MAX - 1) {
                 char *t;
 
-                t = strndupa(x, SD_ID128_STRING_MAX - 1);
+                t = strndupa_safe(x, SD_ID128_STRING_MAX - 1);
                 r = sd_id128_from_string(t, &id);
                 if (r >= 0)
                         x += SD_ID128_STRING_MAX - 1;
@@ -1874,13 +1874,13 @@ static int setup_keys(void) {
                 return log_oom();
 
         mpk_size = FSPRG_mskinbytes(FSPRG_RECOMMENDED_SECPAR);
-        mpk = alloca(mpk_size);
+        mpk = alloca_safe(mpk_size);
 
         seed_size = FSPRG_RECOMMENDED_SEEDLEN;
-        seed = alloca(seed_size);
+        seed = alloca_safe(seed_size);
 
         state_size = FSPRG_stateinbytes(FSPRG_RECOMMENDED_SECPAR);
-        state = alloca(state_size);
+        state = alloca_safe(state_size);
 
         log_info("Generating seed...");
         r = genuine_random_bytes(seed, seed_size, RANDOM_BLOCK);
index 0a90091a86335c0fce27b6b55eea1093b21e7eba..cbff5036a422dde72fee78e9b6ac18ffbdcad442 100644 (file)
@@ -36,6 +36,7 @@
 #include "syslog-util.h"
 #include "tmpfile-util.h"
 #include "unit-name.h"
+#include "user-util.h"
 
 #define STDOUT_STREAMS_MAX 4096
 
@@ -663,6 +664,7 @@ int stdout_stream_install(Server *s, int fd, StdoutStream **ret) {
         *stream = (StdoutStream) {
                 .fd = -1,
                 .priority = LOG_INFO,
+                .ucred = UCRED_INVALID,
         };
 
         xsprintf(stream->id_field, "_STREAM_ID=" SD_ID128_FORMAT_STR, SD_ID128_FORMAT_VAL(id));
@@ -727,9 +729,9 @@ static int stdout_stream_new(sd_event_source *es, int listen_fd, uint32_t revent
         }
 
         if (s->n_stdout_streams >= STDOUT_STREAMS_MAX) {
-                struct ucred u;
+                struct ucred u = UCRED_INVALID;
 
-                r = getpeercred(fd, &u);
+                (void) getpeercred(fd, &u);
 
                 /* By closing fd here we make sure that the client won't wait too long for journald to
                  * gather all the data it adds to the error message to find out that the connection has
@@ -737,7 +739,7 @@ static int stdout_stream_new(sd_event_source *es, int listen_fd, uint32_t revent
                  */
                 fd = safe_close(fd);
 
-                server_driver_message(s, r < 0 ? 0 : u.pid, NULL, LOG_MESSAGE("Too many stdout streams, refusing connection."), NULL);
+                server_driver_message(s, u.pid, NULL, LOG_MESSAGE("Too many stdout streams, refusing connection."), NULL);
                 return 0;
         }
 
index 3313e53f74ce47838dc1fd68508f9dac1b28d93f..23021f7bad8c38ccf8e6b9abfd2c47a25c3f75fb 100644 (file)
@@ -207,7 +207,7 @@ int dhcp_identifier_set_iaid(
         if (legacy_unstable_byteorder)
                 /* for historical reasons (a bug), the bits were swapped and thus
                  * the result was endianness dependent. Preserve that behavior. */
-                id32 = __bswap_32(id32);
+                id32 = bswap_32(id32);
         else
                 /* the fixed behavior returns a stable byte order. Since LE is expected
                  * to be more common, swap the bytes on LE to give the same as legacy
index 4eb56aa8c9ec5dd6b165175239848ffade22a537..31482d7717594c7923f96577f054ffd2bd927727 100644 (file)
@@ -93,6 +93,7 @@ typedef struct DHCP6IA {
 
 typedef struct sd_dhcp6_client sd_dhcp6_client;
 
+bool dhcp6_option_can_request(uint16_t option);
 int dhcp6_option_append(uint8_t **buf, size_t *buflen, uint16_t code,
                         size_t optlen, const void *optval);
 int dhcp6_option_append_ia(uint8_t **buf, size_t *buflen, const DHCP6IA *ia);
index 0276ce693cbf6b31f5f83bedbfca421b676591c3..42792d1d2fc1e940c5ce6a0817fa044c32343b2f 100644 (file)
 #define DHCP6_OPTION_IA_PD_LEN (sizeof(struct ia_pd))
 #define DHCP6_OPTION_IA_TA_LEN (sizeof(struct ia_ta))
 
+bool dhcp6_option_can_request(uint16_t option) {
+        /* See Client ORO field in
+         * https://www.iana.org/assignments/dhcpv6-parameters/dhcpv6-parameters.xhtml#dhcpv6-parameters-2 */
+
+        switch (option) {
+        case SD_DHCP6_OPTION_CLIENTID:
+        case SD_DHCP6_OPTION_SERVERID:
+        case SD_DHCP6_OPTION_IA_NA:
+        case SD_DHCP6_OPTION_IA_TA:
+        case SD_DHCP6_OPTION_IAADDR:
+        case SD_DHCP6_OPTION_ORO:
+        case SD_DHCP6_OPTION_PREFERENCE:
+        case SD_DHCP6_OPTION_ELAPSED_TIME:
+        case SD_DHCP6_OPTION_RELAY_MSG:
+        case SD_DHCP6_OPTION_AUTH:
+        case SD_DHCP6_OPTION_UNICAST:
+        case SD_DHCP6_OPTION_STATUS_CODE:
+        case SD_DHCP6_OPTION_RAPID_COMMIT:
+        case SD_DHCP6_OPTION_USER_CLASS:
+        case SD_DHCP6_OPTION_VENDOR_CLASS:
+                return false;
+        case SD_DHCP6_OPTION_VENDOR_OPTS:
+                return true;
+        case SD_DHCP6_OPTION_INTERFACE_ID:
+        case SD_DHCP6_OPTION_RECONF_MSG:
+        case SD_DHCP6_OPTION_RECONF_ACCEPT:
+                return false;
+        case SD_DHCP6_OPTION_SIP_SERVER_DOMAIN_NAME:
+        case SD_DHCP6_OPTION_SIP_SERVER_ADDRESS:
+        case SD_DHCP6_OPTION_DNS_SERVERS:
+        case SD_DHCP6_OPTION_DOMAIN_LIST:
+                return true;
+        case SD_DHCP6_OPTION_IA_PD:
+        case SD_DHCP6_OPTION_IA_PD_PREFIX:
+                return false;
+        case SD_DHCP6_OPTION_NIS_SERVERS:
+        case SD_DHCP6_OPTION_NISP_SERVERS:
+        case SD_DHCP6_OPTION_NIS_DOMAIN_NAME:
+        case SD_DHCP6_OPTION_NISP_DOMAIN_NAME:
+        case SD_DHCP6_OPTION_SNTP_SERVERS:
+        case SD_DHCP6_OPTION_INFORMATION_REFRESH_TIME:
+        case SD_DHCP6_OPTION_BCMCS_SERVER_D:
+        case SD_DHCP6_OPTION_BCMCS_SERVER_A:
+        case SD_DHCP6_OPTION_GEOCONF_CIVIC:
+                return true;
+        case SD_DHCP6_OPTION_REMOTE_ID:
+        case SD_DHCP6_OPTION_SUBSCRIBER_ID:
+                return false;
+        case SD_DHCP6_OPTION_CLIENT_FQDN:
+        case SD_DHCP6_OPTION_PANA_AGENT:
+        case SD_DHCP6_OPTION_NEW_POSIX_TIMEZONE:
+        case SD_DHCP6_OPTION_NEW_TZDB_TIMEZONE:
+                return true;
+        case SD_DHCP6_OPTION_ERO:
+        case SD_DHCP6_OPTION_LQ_QUERY:
+        case SD_DHCP6_OPTION_CLIENT_DATA:
+        case SD_DHCP6_OPTION_CLT_TIME:
+        case SD_DHCP6_OPTION_LQ_RELAY_DATA:
+        case SD_DHCP6_OPTION_LQ_CLIENT_LINK:
+                return false;
+        case SD_DHCP6_OPTION_MIP6_HNIDF:
+        case SD_DHCP6_OPTION_MIP6_VDINF:
+        case SD_DHCP6_OPTION_V6_LOST:
+        case SD_DHCP6_OPTION_CAPWAP_AC_V6:
+                return true;
+        case SD_DHCP6_OPTION_RELAY_ID:
+                return false;
+        case SD_DHCP6_OPTION_IPV6_ADDRESS_MOS:
+        case SD_DHCP6_OPTION_IPV6_FQDN_MOS:
+        case SD_DHCP6_OPTION_NTP_SERVER:
+        case SD_DHCP6_OPTION_V6_ACCESS_DOMAIN:
+        case SD_DHCP6_OPTION_SIP_UA_CS_LIST:
+        case SD_DHCP6_OPTION_BOOTFILE_URL:
+        case SD_DHCP6_OPTION_BOOTFILE_PARAM:
+                return true;
+        case SD_DHCP6_OPTION_CLIENT_ARCH_TYPE:
+                return false;
+        case SD_DHCP6_OPTION_NII:
+        case SD_DHCP6_OPTION_GEOLOCATION:
+        case SD_DHCP6_OPTION_AFTR_NAME:
+        case SD_DHCP6_OPTION_ERP_LOCAL_DOMAIN_NAME:
+                return true;
+        case SD_DHCP6_OPTION_RSOO:
+                return false;
+        case SD_DHCP6_OPTION_PD_EXCLUDE:
+                return true;
+        case SD_DHCP6_OPTION_VSS:
+                return false;
+        case SD_DHCP6_OPTION_MIP6_IDINF:
+        case SD_DHCP6_OPTION_MIP6_UDINF:
+        case SD_DHCP6_OPTION_MIP6_HNP:
+        case SD_DHCP6_OPTION_MIP6_HAA:
+        case SD_DHCP6_OPTION_MIP6_HAF:
+        case SD_DHCP6_OPTION_RDNSS_SELECTION:
+        case SD_DHCP6_OPTION_KRB_PRINCIPAL_NAME:
+        case SD_DHCP6_OPTION_KRB_REALM_NAME:
+        case SD_DHCP6_OPTION_KRB_DEFAULT_REALM_NAME:
+        case SD_DHCP6_OPTION_KRB_KDC:
+                return true;
+        case SD_DHCP6_OPTION_CLIENT_LINKLAYER_ADDR:
+        case SD_DHCP6_OPTION_LINK_ADDRESS:
+        case SD_DHCP6_OPTION_RADIUS:
+                return false;
+        case SD_DHCP6_OPTION_SOL_MAX_RT:
+        case SD_DHCP6_OPTION_INF_MAX_RT:
+        case SD_DHCP6_OPTION_ADDRSEL:
+        case SD_DHCP6_OPTION_ADDRSEL_TABLE:
+        case SD_DHCP6_OPTION_V6_PCP_SERVER:
+                return true;
+        case SD_DHCP6_OPTION_DHCPV4_MSG:
+                return false;
+        case SD_DHCP6_OPTION_DHCP4_O_DHCP6_SERVER:
+                return true;
+        case SD_DHCP6_OPTION_S46_RULE:
+                return false;
+        case SD_DHCP6_OPTION_S46_BR:
+                return true;
+        case SD_DHCP6_OPTION_S46_DMR:
+        case SD_DHCP6_OPTION_S46_V4V6BIND:
+        case SD_DHCP6_OPTION_S46_PORTPARAMS:
+                return false;
+        case SD_DHCP6_OPTION_S46_CONT_MAPE:
+        case SD_DHCP6_OPTION_S46_CONT_MAPT:
+        case SD_DHCP6_OPTION_S46_CONT_LW:
+        case SD_DHCP6_OPTION_4RD:
+        case SD_DHCP6_OPTION_4RD_MAP_RULE:
+        case SD_DHCP6_OPTION_4RD_NON_MAP_RULE:
+                return true;
+        case SD_DHCP6_OPTION_LQ_BASE_TIME:
+        case SD_DHCP6_OPTION_LQ_START_TIME:
+        case SD_DHCP6_OPTION_LQ_END_TIME:
+                return false;
+        case SD_DHCP6_OPTION_CAPTIVE_PORTAL:
+        case SD_DHCP6_OPTION_MPL_PARAMETERS:
+                return true;
+        case SD_DHCP6_OPTION_ANI_ATT:
+        case SD_DHCP6_OPTION_ANI_NETWORK_NAME:
+        case SD_DHCP6_OPTION_ANI_AP_NAME:
+        case SD_DHCP6_OPTION_ANI_AP_BSSID:
+        case SD_DHCP6_OPTION_ANI_OPERATOR_ID:
+        case SD_DHCP6_OPTION_ANI_OPERATOR_REALM:
+                return false;
+        case SD_DHCP6_OPTION_S46_PRIORITY:
+                return true;
+        case SD_DHCP6_OPTION_MUD_URL_V6:
+                return false;
+        case SD_DHCP6_OPTION_V6_PREFIX64:
+                return true;
+        case SD_DHCP6_OPTION_F_BINDING_STATUS:
+        case SD_DHCP6_OPTION_F_CONNECT_FLAGS:
+        case SD_DHCP6_OPTION_F_DNS_REMOVAL_INFO:
+        case SD_DHCP6_OPTION_F_DNS_HOST_NAME:
+        case SD_DHCP6_OPTION_F_DNS_ZONE_NAME:
+        case SD_DHCP6_OPTION_F_DNS_FLAGS:
+        case SD_DHCP6_OPTION_F_EXPIRATION_TIME:
+        case SD_DHCP6_OPTION_F_MAX_UNACKED_BNDUPD:
+        case SD_DHCP6_OPTION_F_MCLT:
+        case SD_DHCP6_OPTION_F_PARTNER_LIFETIME:
+        case SD_DHCP6_OPTION_F_PARTNER_LIFETIME_SENT:
+        case SD_DHCP6_OPTION_F_PARTNER_DOWN_TIME:
+        case SD_DHCP6_OPTION_F_PARTNER_RAW_CLT_TIME:
+        case SD_DHCP6_OPTION_F_PROTOCOL_VERSION:
+        case SD_DHCP6_OPTION_F_KEEPALIVE_TIME:
+        case SD_DHCP6_OPTION_F_RECONFIGURE_DATA:
+        case SD_DHCP6_OPTION_F_RELATIONSHIP_NAME:
+        case SD_DHCP6_OPTION_F_SERVER_FLAGS:
+        case SD_DHCP6_OPTION_F_SERVER_STATE:
+        case SD_DHCP6_OPTION_F_START_TIME_OF_STATE:
+        case SD_DHCP6_OPTION_F_STATE_EXPIRATION_TIME:
+        case SD_DHCP6_OPTION_RELAY_PORT:
+                return false;
+        case SD_DHCP6_OPTION_V6_SZTP_REDIRECT:
+        case SD_DHCP6_OPTION_S46_BIND_IPV6_PREFIX:
+                return true;
+        case SD_DHCP6_OPTION_IA_LL:
+        case SD_DHCP6_OPTION_LLADDR:
+        case SD_DHCP6_OPTION_SLAP_QUAD:
+                return false;
+        case SD_DHCP6_OPTION_V6_DOTS_RI:
+        case SD_DHCP6_OPTION_V6_DOTS_ADDRESS:
+        case SD_DHCP6_OPTION_IPV6_ADDRESS_ANDSF:
+                return true;
+        default:
+                return false;
+        }
+}
+
 static int option_append_hdr(uint8_t **buf, size_t *buflen, uint16_t optcode, size_t optlen) {
         DHCP6Option *option;
 
@@ -273,7 +460,7 @@ int dhcp6_option_append_fqdn(uint8_t **buf, size_t *buflen, const char *fqdn) {
         if (dns_name_is_single_label(fqdn))
                 r--;
 
-        r = dhcp6_option_append(buf, buflen, SD_DHCP6_OPTION_FQDN, 1 + r, buffer);
+        r = dhcp6_option_append(buf, buflen, SD_DHCP6_OPTION_CLIENT_FQDN, 1 + r, buffer);
 
         return r;
 }
index c700363803bcd5471dcdc1060d530c698f8d543f..5d2af439e280324deaea094b3afb280ab4b4853e 100644 (file)
@@ -5,6 +5,7 @@
   Copyright Â© 2014 Intel Corporation. All rights reserved.
 ***/
 
+#include <errno.h>
 #include <netinet/ip6.h>
 #include <netinet/udp.h>
 
@@ -36,57 +37,83 @@ enum {
         DHCP6_PORT_CLIENT                       = 546,
 };
 
-#define DHCP6_INF_TIMEOUT                       1 * USEC_PER_SEC
-#define DHCP6_INF_MAX_RT                        120 * USEC_PER_SEC
-#define DHCP6_SOL_MAX_DELAY                     1 * USEC_PER_SEC
-#define DHCP6_SOL_TIMEOUT                       1 * USEC_PER_SEC
-#define DHCP6_SOL_MAX_RT                        120 * USEC_PER_SEC
-#define DHCP6_REQ_TIMEOUT                       1 * USEC_PER_SEC
-#define DHCP6_REQ_MAX_RT                        120 * USEC_PER_SEC
+#define DHCP6_INF_TIMEOUT                       (1 * USEC_PER_SEC)
+#define DHCP6_INF_MAX_RT                        (120 * USEC_PER_SEC)
+#define DHCP6_SOL_MAX_DELAY                     (1 * USEC_PER_SEC)
+#define DHCP6_SOL_TIMEOUT                       (1 * USEC_PER_SEC)
+#define DHCP6_SOL_MAX_RT                        (120 * USEC_PER_SEC)
+#define DHCP6_REQ_TIMEOUT                       (1 * USEC_PER_SEC)
+#define DHCP6_REQ_MAX_RT                        (120 * USEC_PER_SEC)
 #define DHCP6_REQ_MAX_RC                        10
-#define DHCP6_REN_TIMEOUT                       10 * USEC_PER_SEC
-#define DHCP6_REN_MAX_RT                        600 * USEC_PER_SEC
-#define DHCP6_REB_TIMEOUT                       10 * USEC_PER_SEC
-#define DHCP6_REB_MAX_RT                        600 * USEC_PER_SEC
+#define DHCP6_REN_TIMEOUT                       (10 * USEC_PER_SEC)
+#define DHCP6_REN_MAX_RT                        (600 * USEC_PER_SEC)
+#define DHCP6_REB_TIMEOUT                       (10 * USEC_PER_SEC)
+#define DHCP6_REB_MAX_RT                        (600 * USEC_PER_SEC)
 
-enum DHCP6State {
-        DHCP6_STATE_STOPPED                     = 0,
-        DHCP6_STATE_INFORMATION_REQUEST         = 1,
-        DHCP6_STATE_SOLICITATION                = 2,
-        DHCP6_STATE_REQUEST                     = 3,
-        DHCP6_STATE_BOUND                       = 4,
-        DHCP6_STATE_RENEW                       = 5,
-        DHCP6_STATE_REBIND                      = 6,
-};
+typedef enum DHCP6State {
+        DHCP6_STATE_STOPPED,
+        DHCP6_STATE_INFORMATION_REQUEST,
+        DHCP6_STATE_SOLICITATION,
+        DHCP6_STATE_REQUEST,
+        DHCP6_STATE_BOUND,
+        DHCP6_STATE_RENEW,
+        DHCP6_STATE_REBIND,
+        _DHCP6_STATE_MAX,
+        _DHCP6_STATE_INVALID = -EINVAL,
+} DHCP6State;
 
-enum {
-        DHCP6_SOLICIT                           = 1,
-        DHCP6_ADVERTISE                         = 2,
-        DHCP6_REQUEST                           = 3,
-        DHCP6_CONFIRM                           = 4,
-        DHCP6_RENEW                             = 5,
-        DHCP6_REBIND                            = 6,
-        DHCP6_REPLY                             = 7,
-        DHCP6_RELEASE                           = 8,
-        DHCP6_DECLINE                           = 9,
-        DHCP6_RECONFIGURE                       = 10,
-        DHCP6_INFORMATION_REQUEST               = 11,
-        DHCP6_RELAY_FORW                        = 12,
-        DHCP6_RELAY_REPL                        = 13,
-        _DHCP6_MESSAGE_MAX                      = 14,
-};
+/* https://www.iana.org/assignments/dhcpv6-parameters/dhcpv6-parameters.xhtml#dhcpv6-parameters-1 */
+typedef enum DHCP6MessageType {
+        DHCP6_MESSAGE_SOLICIT                   = 1,  /* RFC 8415 */
+        DHCP6_MESSAGE_ADVERTISE                 = 2,  /* RFC 8415 */
+        DHCP6_MESSAGE_REQUEST                   = 3,  /* RFC 8415 */
+        DHCP6_MESSAGE_CONFIRM                   = 4,  /* RFC 8415 */
+        DHCP6_MESSAGE_RENEW                     = 5,  /* RFC 8415 */
+        DHCP6_MESSAGE_REBIND                    = 6,  /* RFC 8415 */
+        DHCP6_MESSAGE_REPLY                     = 7,  /* RFC 8415 */
+        DHCP6_MESSAGE_RELEASE                   = 8,  /* RFC 8415 */
+        DHCP6_MESSAGE_DECLINE                   = 9,  /* RFC 8415 */
+        DHCP6_MESSAGE_RECONFIGURE               = 10, /* RFC 8415 */
+        DHCP6_MESSAGE_INFORMATION_REQUEST       = 11, /* RFC 8415 */
+        DHCP6_MESSAGE_RELAY_FORWARD             = 12, /* RFC 8415 */
+        DHCP6_MESSAGE_RELAY_REPLY               = 13, /* RFC 8415 */
+        DHCP6_MESSAGE_LEASE_QUERY               = 14, /* RFC 5007 */
+        DHCP6_MESSAGE_LEASE_QUERY_REPLY         = 15, /* RFC 5007 */
+        DHCP6_MESSAGE_LEASE_QUERY_DONE          = 16, /* RFC 5460 */
+        DHCP6_MESSAGE_LEASE_QUERY_DATA          = 17, /* RFC 5460 */
+        DHCP6_MESSAGE_RECONFIGURE_REQUEST       = 18, /* RFC 6977 */
+        DHCP6_MESSAGE_RECONFIGURE_REPLY         = 19, /* RFC 6977 */
+        DHCP6_MESSAGE_DHCPV4_QUERY              = 20, /* RFC 7341 */
+        DHCP6_MESSAGE_DHCPV4_RESPONSE           = 21, /* RFC 7341 */
+        DHCP6_MESSAGE_ACTIVE_LEASE_QUERY        = 22, /* RFC 7653 */
+        DHCP6_MESSAGE_START_TLS                 = 23, /* RFC 7653 */
+        DHCP6_MESSAGE_BINDING_UPDATE            = 24, /* RFC 8156 */
+        DHCP6_MESSAGE_BINDING_REPLY             = 25, /* RFC 8156 */
+        DHCP6_MESSAGE_POOL_REQUEST              = 26, /* RFC 8156 */
+        DHCP6_MESSAGE_POOL_RESPONSE             = 27, /* RFC 8156 */
+        DHCP6_MESSAGE_UPDATE_REQUEST            = 28, /* RFC 8156 */
+        DHCP6_MESSAGE_UPDATE_REQUEST_ALL        = 29, /* RFC 8156 */
+        DHCP6_MESSAGE_UPDATE_DONE               = 30, /* RFC 8156 */
+        DHCP6_MESSAGE_CONNECT                   = 31, /* RFC 8156 */
+        DHCP6_MESSAGE_CONNECT_REPLY             = 32, /* RFC 8156 */
+        DHCP6_MESSAGE_DISCONNECT                = 33, /* RFC 8156 */
+        DHCP6_MESSAGE_STATE                     = 34, /* RFC 8156 */
+        DHCP6_MESSAGE_CONTACT                   = 35, /* RFC 8156 */
+        _DHCP6_MESSAGE_TYPE_MAX,
+        _DHCP6_MESSAGE_TYPE_INVALID = -EINVAL,
+} DHCP6MessageType;
 
-enum {
+typedef enum DHCP6NTPSubOption {
         DHCP6_NTP_SUBOPTION_SRV_ADDR            = 1,
         DHCP6_NTP_SUBOPTION_MC_ADDR             = 2,
         DHCP6_NTP_SUBOPTION_SRV_FQDN            = 3,
-};
+} DHCP6NTPSubOption;
 
 /*
  * RFC 8415, RFC 5007 and RFC 7653 status codes:
  * https://www.iana.org/assignments/dhcpv6-parameters/dhcpv6-parameters.xhtml#dhcpv6-parameters-5
  */
-enum {
+typedef enum DHCP6Status {
         DHCP6_STATUS_SUCCESS                      = 0,
         DHCP6_STATUS_UNSPEC_FAIL                  = 1,
         DHCP6_STATUS_NO_ADDRS_AVAIL               = 2,
@@ -110,11 +137,12 @@ enum {
         DHCP6_STATUS_SERVER_SHUTTING_DOWN         = 20,
         DHCP6_STATUS_DNS_UPDATE_NOT_SUPPORTED     = 21,
         DHCP6_STATUS_EXCESSIVE_TIME_SKEW          = 22,
-        _DHCP6_STATUS_MAX                         = 23,
-};
+        _DHCP6_STATUS_MAX,
+        _DHCP6_STATUS_INVALID = -EINVAL,
+} DHCP6Status;
 
-enum {
-        DHCP6_FQDN_FLAG_S = (1 << 0),
-        DHCP6_FQDN_FLAG_O = (1 << 1),
-        DHCP6_FQDN_FLAG_N = (1 << 2),
-};
+typedef enum DHCP6FQDNFlag {
+        DHCP6_FQDN_FLAG_S = 1 << 0,
+        DHCP6_FQDN_FLAG_O = 1 << 1,
+        DHCP6_FQDN_FLAG_N = 1 << 2,
+} DHCP6FQDNFlag;
index 87dd8c84d11b5f1c17717acd8891a117a3516b0b..aacdf0698079d6c1e4ac7aa565abb63a2137f11e 100644 (file)
 #define IRT_MINIMUM (600 * USEC_PER_SEC)
 
 /* what to request from the server, addresses (IA_NA) and/or prefixes (IA_PD) */
-enum {
-        DHCP6_REQUEST_IA_NA                     = 1,
-        DHCP6_REQUEST_IA_TA                     = 2, /* currently not used */
-        DHCP6_REQUEST_IA_PD                     = 4,
-};
+typedef enum DHCP6RequestIA {
+        DHCP6_REQUEST_IA_NA = 1 << 0,
+        DHCP6_REQUEST_IA_TA = 1 << 1, /* currently not used */
+        DHCP6_REQUEST_IA_PD = 1 << 2,
+} DHCP6RequestIA;
 
 struct sd_dhcp6_client {
         unsigned n_ref;
 
-        enum DHCP6State state;
+        DHCP6State state;
         sd_event *event;
         int event_priority;
         int ifindex;
@@ -58,7 +58,7 @@ struct sd_dhcp6_client {
         DHCP6IA ia_pd;
         sd_event_source *timeout_t1;
         sd_event_source *timeout_t2;
-        unsigned request;
+        DHCP6RequestIA request_ia;
         be32_t transaction_id;
         usec_t transaction_start;
         struct sd_dhcp6_lease *lease;
@@ -96,20 +96,42 @@ static const uint16_t default_req_opts[] = {
         SD_DHCP6_OPTION_SNTP_SERVERS,
 };
 
-const char * dhcp6_message_type_table[_DHCP6_MESSAGE_MAX] = {
-        [DHCP6_SOLICIT] = "SOLICIT",
-        [DHCP6_ADVERTISE] = "ADVERTISE",
-        [DHCP6_REQUEST] = "REQUEST",
-        [DHCP6_CONFIRM] = "CONFIRM",
-        [DHCP6_RENEW] = "RENEW",
-        [DHCP6_REBIND] = "REBIND",
-        [DHCP6_REPLY] = "REPLY",
-        [DHCP6_RELEASE] = "RELEASE",
-        [DHCP6_DECLINE] = "DECLINE",
-        [DHCP6_RECONFIGURE] = "RECONFIGURE",
-        [DHCP6_INFORMATION_REQUEST] = "INFORMATION-REQUEST",
-        [DHCP6_RELAY_FORW] = "RELAY-FORW",
-        [DHCP6_RELAY_REPL] = "RELAY-REPL",
+const char * dhcp6_message_type_table[_DHCP6_MESSAGE_TYPE_MAX] = {
+        [DHCP6_MESSAGE_SOLICIT]             = "Solicit",
+        [DHCP6_MESSAGE_ADVERTISE]           = "Advertise",
+        [DHCP6_MESSAGE_REQUEST]             = "Request",
+        [DHCP6_MESSAGE_CONFIRM]             = "Confirm",
+        [DHCP6_MESSAGE_RENEW]               = "Renew",
+        [DHCP6_MESSAGE_REBIND]              = "Rebind",
+        [DHCP6_MESSAGE_REPLY]               = "Reply",
+        [DHCP6_MESSAGE_RELEASE]             = "Release",
+        [DHCP6_MESSAGE_DECLINE]             = "Decline",
+        [DHCP6_MESSAGE_RECONFIGURE]         = "Reconfigure",
+        [DHCP6_MESSAGE_INFORMATION_REQUEST] = "Information Request",
+        [DHCP6_MESSAGE_RELAY_FORWARD]       = "Relay Forward",
+        [DHCP6_MESSAGE_RELAY_REPLY]         = "Relay Reply",
+        [DHCP6_MESSAGE_LEASE_QUERY]         = "Lease Query",
+        [DHCP6_MESSAGE_LEASE_QUERY_REPLY]   = "Lease Query Reply",
+        [DHCP6_MESSAGE_LEASE_QUERY_DONE]    = "Lease Query Done",
+        [DHCP6_MESSAGE_LEASE_QUERY_DATA]    = "Lease Query Data",
+        [DHCP6_MESSAGE_RECONFIGURE_REQUEST] = "Reconfigure Request",
+        [DHCP6_MESSAGE_RECONFIGURE_REPLY]   = "Reconfigure Reply",
+        [DHCP6_MESSAGE_DHCPV4_QUERY]        = "DHCPv4 Query",
+        [DHCP6_MESSAGE_DHCPV4_RESPONSE]     = "DHCPv4 Response",
+        [DHCP6_MESSAGE_ACTIVE_LEASE_QUERY]  = "Active Lease Query",
+        [DHCP6_MESSAGE_START_TLS]           = "Start TLS",
+        [DHCP6_MESSAGE_BINDING_UPDATE]      = "Binding Update",
+        [DHCP6_MESSAGE_BINDING_REPLY]       = "Binding Reply",
+        [DHCP6_MESSAGE_POOL_REQUEST]        = "Pool Request",
+        [DHCP6_MESSAGE_POOL_RESPONSE]       = "Pool Response",
+        [DHCP6_MESSAGE_UPDATE_REQUEST]      = "Update Request",
+        [DHCP6_MESSAGE_UPDATE_REQUEST_ALL]  = "Update Request All",
+        [DHCP6_MESSAGE_UPDATE_DONE]         = "Update Done",
+        [DHCP6_MESSAGE_CONNECT]             = "Connect",
+        [DHCP6_MESSAGE_CONNECT_REPLY]       = "Connect Reply",
+        [DHCP6_MESSAGE_DISCONNECT]          = "Disconnect",
+        [DHCP6_MESSAGE_STATE]               = "State",
+        [DHCP6_MESSAGE_CONTACT]             = "Contact",
 };
 
 DEFINE_STRING_TABLE_LOOKUP(dhcp6_message_type, int);
@@ -145,7 +167,7 @@ DEFINE_STRING_TABLE_LOOKUP(dhcp6_message_status, int);
 #define DHCP6_CLIENT_DONT_DESTROY(client) \
         _cleanup_(sd_dhcp6_client_unrefp) _unused_ sd_dhcp6_client *_dont_destroy_##client = sd_dhcp6_client_ref(client)
 
-static int client_start(sd_dhcp6_client *client, enum DHCP6State state);
+static int client_start(sd_dhcp6_client *client, DHCP6State state);
 
 int sd_dhcp6_client_set_callback(
                 sd_dhcp6_client *client,
@@ -465,7 +487,7 @@ int sd_dhcp6_client_set_request_option(sd_dhcp6_client *client, uint16_t option)
         assert_return(client, -EINVAL);
         assert_return(client->state == DHCP6_STATE_STOPPED, -EBUSY);
 
-        if (option <= 0 || option >= UINT8_MAX)
+        if (!dhcp6_option_can_request(option))
                 return -EINVAL;
 
         for (t = 0; t < client->req_opts_len; t++)
@@ -538,7 +560,7 @@ int sd_dhcp6_client_get_prefix_delegation(sd_dhcp6_client *client, int *delegati
         assert_return(client, -EINVAL);
         assert_return(delegation, -EINVAL);
 
-        *delegation = FLAGS_SET(client->request, DHCP6_REQUEST_IA_PD);
+        *delegation = FLAGS_SET(client->request_ia, DHCP6_REQUEST_IA_PD);
 
         return 0;
 }
@@ -546,7 +568,7 @@ int sd_dhcp6_client_get_prefix_delegation(sd_dhcp6_client *client, int *delegati
 int sd_dhcp6_client_set_prefix_delegation(sd_dhcp6_client *client, int delegation) {
         assert_return(client, -EINVAL);
 
-        SET_FLAG(client->request, DHCP6_REQUEST_IA_PD, delegation);
+        SET_FLAG(client->request_ia, DHCP6_REQUEST_IA_PD, delegation);
 
         return 0;
 }
@@ -555,7 +577,7 @@ int sd_dhcp6_client_get_address_request(sd_dhcp6_client *client, int *request) {
         assert_return(client, -EINVAL);
         assert_return(request, -EINVAL);
 
-        *request = FLAGS_SET(client->request, DHCP6_REQUEST_IA_NA);
+        *request = FLAGS_SET(client->request_ia, DHCP6_REQUEST_IA_NA);
 
         return 0;
 }
@@ -563,7 +585,7 @@ int sd_dhcp6_client_get_address_request(sd_dhcp6_client *client, int *request) {
 int sd_dhcp6_client_set_address_request(sd_dhcp6_client *client, int request) {
         assert_return(client, -EINVAL);
 
-        SET_FLAG(client->request, DHCP6_REQUEST_IA_NA, request);
+        SET_FLAG(client->request_ia, DHCP6_REQUEST_IA_NA, request);
 
         return 0;
 }
@@ -668,11 +690,11 @@ static int client_send_message(sd_dhcp6_client *client, usec_t time_now) {
 
         switch(client->state) {
         case DHCP6_STATE_INFORMATION_REQUEST:
-                message->type = DHCP6_INFORMATION_REQUEST;
+                message->type = DHCP6_MESSAGE_INFORMATION_REQUEST;
 
                 if (client->mudurl) {
                         r = dhcp6_option_append(&opt, &optlen,
-                                                SD_DHCP6_OPTION_MUD_URL, strlen(client->mudurl),
+                                                SD_DHCP6_OPTION_MUD_URL_V6, strlen(client->mudurl),
                                                 client->mudurl);
                         if (r < 0)
                                 return r;
@@ -681,14 +703,14 @@ static int client_send_message(sd_dhcp6_client *client, usec_t time_now) {
                 break;
 
         case DHCP6_STATE_SOLICITATION:
-                message->type = DHCP6_SOLICIT;
+                message->type = DHCP6_MESSAGE_SOLICIT;
 
                 r = dhcp6_option_append(&opt, &optlen,
                                         SD_DHCP6_OPTION_RAPID_COMMIT, 0, NULL);
                 if (r < 0)
                         return r;
 
-                if (FLAGS_SET(client->request, DHCP6_REQUEST_IA_NA)) {
+                if (FLAGS_SET(client->request_ia, DHCP6_REQUEST_IA_NA)) {
                         r = dhcp6_option_append_ia(&opt, &optlen,
                                                    &client->ia_na);
                         if (r < 0)
@@ -703,7 +725,7 @@ static int client_send_message(sd_dhcp6_client *client, usec_t time_now) {
 
                 if (client->mudurl) {
                         r = dhcp6_option_append(&opt, &optlen,
-                                                SD_DHCP6_OPTION_MUD_URL, strlen(client->mudurl),
+                                                SD_DHCP6_OPTION_MUD_URL_V6, strlen(client->mudurl),
                                                 client->mudurl);
                         if (r < 0)
                                 return r;
@@ -728,7 +750,7 @@ static int client_send_message(sd_dhcp6_client *client, usec_t time_now) {
                                 return r;
                 }
 
-                if (FLAGS_SET(client->request, DHCP6_REQUEST_IA_PD)) {
+                if (FLAGS_SET(client->request_ia, DHCP6_REQUEST_IA_PD)) {
                         r = dhcp6_option_append_pd(&opt, &optlen, &client->ia_pd, &client->hint_pd_prefix);
                         if (r < 0)
                                 return r;
@@ -740,9 +762,9 @@ static int client_send_message(sd_dhcp6_client *client, usec_t time_now) {
         case DHCP6_STATE_RENEW:
 
                 if (client->state == DHCP6_STATE_REQUEST)
-                        message->type = DHCP6_REQUEST;
+                        message->type = DHCP6_MESSAGE_REQUEST;
                 else
-                        message->type = DHCP6_RENEW;
+                        message->type = DHCP6_MESSAGE_RENEW;
 
                 r = dhcp6_option_append(&opt, &optlen, SD_DHCP6_OPTION_SERVERID,
                                         client->lease->serverid_len,
@@ -750,7 +772,7 @@ static int client_send_message(sd_dhcp6_client *client, usec_t time_now) {
                 if (r < 0)
                         return r;
 
-                if (FLAGS_SET(client->request, DHCP6_REQUEST_IA_NA) && client->lease->ia.addresses) {
+                if (FLAGS_SET(client->request_ia, DHCP6_REQUEST_IA_NA) && client->lease->ia.addresses) {
                         r = dhcp6_option_append_ia(&opt, &optlen,
                                                    &client->lease->ia);
                         if (r < 0)
@@ -765,7 +787,7 @@ static int client_send_message(sd_dhcp6_client *client, usec_t time_now) {
 
                 if (client->mudurl) {
                         r = dhcp6_option_append(&opt, &optlen,
-                                                SD_DHCP6_OPTION_MUD_URL, strlen(client->mudurl),
+                                                SD_DHCP6_OPTION_MUD_URL_V6, strlen(client->mudurl),
                                                 client->mudurl);
                         if (r < 0)
                                 return r;
@@ -789,7 +811,7 @@ static int client_send_message(sd_dhcp6_client *client, usec_t time_now) {
                                 return r;
                 }
 
-                if (FLAGS_SET(client->request, DHCP6_REQUEST_IA_PD) && client->lease->pd.addresses) {
+                if (FLAGS_SET(client->request_ia, DHCP6_REQUEST_IA_PD) && client->lease->pd.addresses) {
                         r = dhcp6_option_append_pd(&opt, &optlen, &client->lease->pd, NULL);
                         if (r < 0)
                                 return r;
@@ -798,9 +820,9 @@ static int client_send_message(sd_dhcp6_client *client, usec_t time_now) {
                 break;
 
         case DHCP6_STATE_REBIND:
-                message->type = DHCP6_REBIND;
+                message->type = DHCP6_MESSAGE_REBIND;
 
-                if (FLAGS_SET(client->request, DHCP6_REQUEST_IA_NA)) {
+                if (FLAGS_SET(client->request_ia, DHCP6_REQUEST_IA_NA)) {
                         r = dhcp6_option_append_ia(&opt, &optlen, &client->lease->ia);
                         if (r < 0)
                                 return r;
@@ -814,7 +836,7 @@ static int client_send_message(sd_dhcp6_client *client, usec_t time_now) {
 
                 if (client->mudurl) {
                         r = dhcp6_option_append(&opt, &optlen,
-                                                SD_DHCP6_OPTION_MUD_URL, strlen(client->mudurl),
+                                                SD_DHCP6_OPTION_MUD_URL_V6, strlen(client->mudurl),
                                                 client->mudurl);
                         if (r < 0)
                                 return r;
@@ -838,7 +860,7 @@ static int client_send_message(sd_dhcp6_client *client, usec_t time_now) {
                                 return r;
                 }
 
-                if (FLAGS_SET(client->request, DHCP6_REQUEST_IA_PD)) {
+                if (FLAGS_SET(client->request_ia, DHCP6_REQUEST_IA_PD)) {
                         r = dhcp6_option_append_pd(&opt, &optlen, &client->lease->pd, NULL);
                         if (r < 0)
                                 return r;
@@ -849,6 +871,8 @@ static int client_send_message(sd_dhcp6_client *client, usec_t time_now) {
         case DHCP6_STATE_STOPPED:
         case DHCP6_STATE_BOUND:
                 return -EINVAL;
+        default:
+                assert_not_reached();
         }
 
         r = dhcp6_option_append(&opt, &optlen, SD_DHCP6_OPTION_ORO,
@@ -926,7 +950,7 @@ static int client_timeout_t1(sd_event_source *s, uint64_t usec, void *userdata)
 static int client_timeout_resend_expire(sd_event_source *s, uint64_t usec, void *userdata) {
         sd_dhcp6_client *client = userdata;
         DHCP6_CLIENT_DONT_DESTROY(client);
-        enum DHCP6State state;
+        DHCP6State state;
 
         assert(s);
         assert(client);
@@ -1017,6 +1041,8 @@ static int client_timeout_resend(sd_event_source *s, uint64_t usec, void *userda
         case DHCP6_STATE_STOPPED:
         case DHCP6_STATE_BOUND:
                 return 0;
+        default:
+                assert_not_reached();
         }
 
         if (max_retransmit_count > 0 &&
@@ -1041,8 +1067,8 @@ static int client_timeout_resend(sd_event_source *s, uint64_t usec, void *userda
                         client->retransmit_time += init_retransmit_time / 10;
 
         } else {
-                if (max_retransmit_time > 0 &&
-                    client->retransmit_time > max_retransmit_time / 2)
+                assert(max_retransmit_time > 0);
+                if (client->retransmit_time > max_retransmit_time / 2)
                         client->retransmit_time = client_timeout_compute_random(max_retransmit_time);
                 else
                         client->retransmit_time += client_timeout_compute_random(client->retransmit_time);
@@ -1270,7 +1296,7 @@ static int client_parse_message(
 
                         break;
 
-                case SD_DHCP6_OPTION_FQDN:
+                case SD_DHCP6_OPTION_CLIENT_FQDN:
                         r = dhcp6_lease_set_fqdn(lease, optval, optlen);
                         if (r < 0)
                                 return r;
@@ -1323,7 +1349,7 @@ static int client_receive_reply(sd_dhcp6_client *client, DHCP6Message *reply, si
         assert(client);
         assert(reply);
 
-        if (reply->type != DHCP6_REPLY)
+        if (reply->type != DHCP6_MESSAGE_REPLY)
                 return 0;
 
         r = dhcp6_lease_new(&lease);
@@ -1354,7 +1380,7 @@ static int client_receive_advertise(sd_dhcp6_client *client, DHCP6Message *adver
         uint8_t pref_advertise = 0, pref_lease = 0;
         int r;
 
-        if (advertise->type != DHCP6_ADVERTISE)
+        if (advertise->type != DHCP6_MESSAGE_ADVERTISE)
                 return 0;
 
         r = dhcp6_lease_new(&lease);
@@ -1426,26 +1452,12 @@ static int client_receive_message(
                 return 0;
         }
 
-        switch(message->type) {
-        case DHCP6_SOLICIT:
-        case DHCP6_REQUEST:
-        case DHCP6_CONFIRM:
-        case DHCP6_RENEW:
-        case DHCP6_REBIND:
-        case DHCP6_RELEASE:
-        case DHCP6_DECLINE:
-        case DHCP6_INFORMATION_REQUEST:
-        case DHCP6_RELAY_FORW:
-        case DHCP6_RELAY_REPL:
-                return 0;
-
-        case DHCP6_ADVERTISE:
-        case DHCP6_REPLY:
-        case DHCP6_RECONFIGURE:
-                break;
-
-        default:
-                log_dhcp6_client(client, "Unknown message type %d", message->type);
+        if (!IN_SET(message->type, DHCP6_MESSAGE_ADVERTISE, DHCP6_MESSAGE_REPLY, DHCP6_MESSAGE_RECONFIGURE)) {
+                const char *type_str = dhcp6_message_type_to_string(message->type);
+                if (type_str)
+                        log_dhcp6_client(client, "Received unexpected %s message, ignoring.", type_str);
+                else
+                        log_dhcp6_client(client, "Received unsupported message type %u, ignoring.", message->type);
                 return 0;
         }
 
@@ -1507,6 +1519,8 @@ static int client_receive_message(
 
         case DHCP6_STATE_STOPPED:
                 return 0;
+        default:
+                assert_not_reached();
         }
 
         log_dhcp6_client(client, "Recv %s",
@@ -1520,14 +1534,14 @@ static int client_get_lifetime(sd_dhcp6_client *client, uint32_t *lifetime_t1,
         assert_return(client, -EINVAL);
         assert_return(client->lease, -EINVAL);
 
-        if (FLAGS_SET(client->request, DHCP6_REQUEST_IA_NA) && client->lease->ia.addresses) {
+        if (FLAGS_SET(client->request_ia, DHCP6_REQUEST_IA_NA) && client->lease->ia.addresses) {
                 *lifetime_t1 = be32toh(client->lease->ia.ia_na.lifetime_t1);
                 *lifetime_t2 = be32toh(client->lease->ia.ia_na.lifetime_t2);
 
                 return 0;
         }
 
-        if (FLAGS_SET(client->request, DHCP6_REQUEST_IA_PD) && client->lease->pd.addresses) {
+        if (FLAGS_SET(client->request_ia, DHCP6_REQUEST_IA_PD) && client->lease->pd.addresses) {
                 *lifetime_t1 = be32toh(client->lease->pd.ia_pd.lifetime_t1);
                 *lifetime_t2 = be32toh(client->lease->pd.ia_pd.lifetime_t2);
 
@@ -1537,7 +1551,7 @@ static int client_get_lifetime(sd_dhcp6_client *client, uint32_t *lifetime_t1,
         return -ENOMSG;
 }
 
-static int client_start(sd_dhcp6_client *client, enum DHCP6State state) {
+static int client_start(sd_dhcp6_client *client, DHCP6State state) {
         int r;
         usec_t timeout, time_now;
         uint32_t lifetime_t1, lifetime_t2;
@@ -1637,6 +1651,8 @@ static int client_start(sd_dhcp6_client *client, enum DHCP6State state) {
                 client->state = state;
 
                 return 0;
+        default:
+                assert_not_reached();
         }
 
         client->transaction_id = random_u32() & htobe32(0x00ffffff);
@@ -1675,7 +1691,7 @@ int sd_dhcp6_client_is_running(sd_dhcp6_client *client) {
 }
 
 int sd_dhcp6_client_start(sd_dhcp6_client *client) {
-        enum DHCP6State state = DHCP6_STATE_SOLICITATION;
+        DHCP6State state = DHCP6_STATE_SOLICITATION;
         int r;
 
         assert_return(client, -EINVAL);
@@ -1686,7 +1702,7 @@ int sd_dhcp6_client_start(sd_dhcp6_client *client) {
         if (client->state != DHCP6_STATE_STOPPED)
                 return -EBUSY;
 
-        if (!client->information_request && !client->request)
+        if (!client->information_request && client->request_ia == 0)
                 return -EINVAL;
 
         r = client_reset(client);
@@ -1814,7 +1830,7 @@ int sd_dhcp6_client_new(sd_dhcp6_client **ret) {
                 .ia_na.type = SD_DHCP6_OPTION_IA_NA,
                 .ia_pd.type = SD_DHCP6_OPTION_IA_PD,
                 .ifindex = -1,
-                .request = DHCP6_REQUEST_IA_NA,
+                .request_ia = DHCP6_REQUEST_IA_NA,
                 .fd = -1,
                 .req_opts_len = ELEMENTSOF(default_req_opts),
                 .hint_pd_prefix.iapdprefix.lifetime_preferred = (be32_t) -1,
index ae33894302b9da9fb290fde65cdb8e701edac376..2d91a406f836f8367f9b6ce842effd32cffec362 100644 (file)
@@ -936,7 +936,7 @@ _public_ int sd_radv_route_prefix_new(sd_radv_route_prefix **ret) {
 
 DEFINE_PUBLIC_TRIVIAL_REF_UNREF_FUNC(sd_radv_route_prefix, sd_radv_route_prefix, mfree);
 
-_public_ int sd_radv_prefix_set_route_prefix(sd_radv_route_prefix *p, const struct in6_addr *in6_addr,
+_public_ int sd_radv_route_prefix_set_prefix(sd_radv_route_prefix *p, const struct in6_addr *in6_addr,
                                              unsigned char prefixlen) {
         assert_return(p, -EINVAL);
         assert_return(in6_addr, -EINVAL);
index 10db7f6c4bcde2d24c0b2c57553ee6b1145020c0..4b11cdbc167d6d4edd90e0ccf769bd729562226b 100644 (file)
@@ -45,7 +45,7 @@ static void test_request_basic(sd_event *e) {
         sd_dhcp_client *client;
 
         if (verbose)
-                printf("* %s\n", __FUNCTION__);
+                printf("* %s\n", __func__);
 
         /* Initialize client without Anonymize settings. */
         r = sd_dhcp_client_new(&client, false);
@@ -105,7 +105,7 @@ static void test_request_anonymize(sd_event *e) {
         sd_dhcp_client *client;
 
         if (verbose)
-                printf("* %s\n", __FUNCTION__);
+                printf("* %s\n", __func__);
 
         /* Initialize client with Anonymize settings. */
         r = sd_dhcp_client_new(&client, true);
@@ -137,7 +137,7 @@ static void test_checksum(void) {
         };
 
         if (verbose)
-                printf("* %s\n", __FUNCTION__);
+                printf("* %s\n", __func__);
 
         assert_se(dhcp_packet_checksum((uint8_t*)&buf, 20) == be16toh(0x78ae));
 }
@@ -158,7 +158,7 @@ static void test_dhcp_identifier_set_iaid(void) {
 #if __BYTE_ORDER == __LITTLE_ENDIAN
         assert_se(iaid == iaid_legacy);
 #else
-        assert_se(iaid == __bswap_32(iaid_legacy));
+        assert_se(iaid == bswap_32(iaid_legacy));
 #endif
 }
 
@@ -279,7 +279,7 @@ static void test_discover_message(sd_event *e) {
         int res, r;
 
         if (verbose)
-                printf("* %s\n", __FUNCTION__);
+                printf("* %s\n", __func__);
 
         r = sd_dhcp_client_new(&client, false);
         assert_se(r >= 0);
@@ -497,7 +497,7 @@ static void test_addr_acq(sd_event *e) {
         int res, r;
 
         if (verbose)
-                printf("* %s\n", __FUNCTION__);
+                printf("* %s\n", __func__);
 
         r = sd_dhcp_client_new(&client, false);
         assert_se(r >= 0);
index d152e7925d75b4da59148987249eab0d3fda2291..c4a0d4ccb2696c68eb416bb2847cd5ae46cb4596 100644 (file)
@@ -121,7 +121,7 @@ static DHCPMessage *create_message(uint8_t *options, uint16_t optlen,
 }
 
 static void test_ignore_opts(uint8_t *descoption, int *descpos, int *desclen) {
-        assert(*descpos >= 0);
+        assert_se(*descpos >= 0);
 
         while (*descpos < *desclen) {
                 switch(descoption[*descpos]) {
index b725f5c30554c81925d6a20d3ee5358da119ec01..055b0c9dee19f8394d4ffe312c2463954e30c12e 100644 (file)
@@ -63,12 +63,16 @@ static int test_client_basic(sd_event *e) {
         assert_se(sd_dhcp6_client_set_fqdn(client, "~host") == -EINVAL);
         assert_se(sd_dhcp6_client_set_fqdn(client, "~host.domain") == -EINVAL);
 
-        assert_se(sd_dhcp6_client_set_request_option(client, SD_DHCP6_OPTION_CLIENTID) == 0);
+        assert_se(sd_dhcp6_client_set_request_option(client, SD_DHCP6_OPTION_CLIENTID) == -EINVAL);
         assert_se(sd_dhcp6_client_set_request_option(client, SD_DHCP6_OPTION_DNS_SERVERS) == -EEXIST);
         assert_se(sd_dhcp6_client_set_request_option(client, SD_DHCP6_OPTION_NTP_SERVER) == -EEXIST);
         assert_se(sd_dhcp6_client_set_request_option(client, SD_DHCP6_OPTION_SNTP_SERVERS) == -EEXIST);
         assert_se(sd_dhcp6_client_set_request_option(client, SD_DHCP6_OPTION_DOMAIN_LIST) == -EEXIST);
-        assert_se(sd_dhcp6_client_set_request_option(client, 10) == 0);
+        assert_se(sd_dhcp6_client_set_request_option(client, 10) == -EINVAL);
+        assert_se(sd_dhcp6_client_set_request_option(client, SD_DHCP6_OPTION_NIS_SERVERS) == 0);
+        assert_se(sd_dhcp6_client_set_request_option(client, SD_DHCP6_OPTION_NISP_SERVERS) == 0);
+        assert_se(sd_dhcp6_client_set_request_option(client, SD_DHCP6_OPTION_NIS_SERVERS) == -EEXIST);
+        assert_se(sd_dhcp6_client_set_request_option(client, SD_DHCP6_OPTION_NISP_SERVERS) == -EEXIST);
 
         assert_se(sd_dhcp6_client_set_information_request(client, 1) >= 0);
         v = 0;
@@ -450,7 +454,7 @@ static int test_advertise_option(sd_event *e) {
 
         assert_se(dhcp6_lease_new(&lease) >= 0);
 
-        assert_se(advertise->type == DHCP6_ADVERTISE);
+        assert_se(advertise->type == DHCP6_MESSAGE_ADVERTISE);
         assert_se((be32toh(advertise->transaction_id) & 0x00ffffff) ==
                   0x0fb4e5);
 
@@ -617,7 +621,7 @@ static int test_client_send_reply(DHCP6Message *request) {
         log_debug("/* %s */", __func__);
 
         reply.transaction_id = request->transaction_id;
-        reply.type = DHCP6_REPLY;
+        reply.type = DHCP6_MESSAGE_REPLY;
 
         memcpy(msg_reply, &reply.transaction_id, 4);
 
@@ -642,7 +646,7 @@ static int test_client_verify_request(DHCP6Message *request, size_t len) {
 
         log_debug("/* %s */", __func__);
 
-        assert_se(request->type == DHCP6_REQUEST);
+        assert_se(request->type == DHCP6_MESSAGE_REQUEST);
         assert_se(dhcp6_lease_new(&lease) >= 0);
 
         len -= sizeof(DHCP6Message);
@@ -696,7 +700,7 @@ static int test_client_verify_request(DHCP6Message *request, size_t len) {
                         assert_se(optlen == 2);
 
                         break;
-                case SD_DHCP6_OPTION_FQDN:
+                case SD_DHCP6_OPTION_CLIENT_FQDN:
                         assert_se(!found_fqdn);
                         found_fqdn = true;
 
@@ -725,7 +729,7 @@ static int test_client_send_advertise(DHCP6Message *solicit) {
         log_debug("/* %s */", __func__);
 
         advertise.transaction_id = solicit->transaction_id;
-        advertise.type = DHCP6_ADVERTISE;
+        advertise.type = DHCP6_MESSAGE_ADVERTISE;
 
         memcpy(msg_advertise, &advertise.transaction_id, 4);
 
@@ -746,7 +750,7 @@ static int test_client_verify_solicit(DHCP6Message *solicit, size_t len) {
 
         log_debug("/* %s */", __func__);
 
-        assert_se(solicit->type == DHCP6_SOLICIT);
+        assert_se(solicit->type == DHCP6_MESSAGE_SOLICIT);
 
         len -= sizeof(DHCP6Message);
 
@@ -784,7 +788,7 @@ static int test_client_verify_solicit(DHCP6Message *solicit, size_t len) {
 
                         break;
 
-                case SD_DHCP6_OPTION_FQDN:
+                case SD_DHCP6_OPTION_CLIENT_FQDN:
                         assert_se(!found_fqdn);
                         found_fqdn = true;
 
@@ -859,7 +863,7 @@ static int test_client_verify_information_request(DHCP6Message *information_requ
 
         log_debug("/* %s */", __func__);
 
-        assert_se(information_request->type == DHCP6_INFORMATION_REQUEST);
+        assert_se(information_request->type == DHCP6_MESSAGE_INFORMATION_REQUEST);
         assert_se(dhcp6_lease_new(&lease) >= 0);
 
         len -= sizeof(DHCP6Message);
index 7985185b33d563fbb76dc1394f39bb60dab29e71..e90e73459d9570f125ab76041a02eaa93ea03685 100644 (file)
@@ -81,7 +81,7 @@ static void test_public_api_setters(sd_event *e) {
                 .ether_addr_octet = {'A', 'B', 'C', '1', '2', '3'}};
 
         if (verbose)
-                printf("* %s\n", __FUNCTION__);
+                printf("* %s\n", __func__);
 
         assert_se(sd_ipv4ll_new(&ll) == 0);
         assert_se(ll);
@@ -130,7 +130,7 @@ static void test_basic_request(sd_event *e) {
                 .ether_addr_octet = {'A', 'B', 'C', '1', '2', '3'}};
 
         if (verbose)
-                printf("* %s\n", __FUNCTION__);
+                printf("* %s\n", __func__);
 
         assert_se(sd_ipv4ll_new(&ll) == 0);
         assert_se(sd_ipv4ll_start(ll) == -EINVAL);
index 927e21b3cdf69d923aa0eed58167b0a556f3b070..4713bc99b5b47bf434b0107d8de263fe8c0c6ea8 100644 (file)
@@ -111,7 +111,7 @@ static int test_rs_hangcheck(sd_event_source *s, uint64_t usec,
 static void test_radv_prefix(void) {
         sd_radv_prefix *p;
 
-        printf("* %s\n", __FUNCTION__);
+        printf("* %s\n", __func__);
 
         assert_se(sd_radv_prefix_new(&p) >= 0);
 
@@ -153,7 +153,7 @@ static void test_radv_prefix(void) {
 static void test_radv(void) {
         sd_radv *ra;
 
-        printf("* %s\n", __FUNCTION__);
+        printf("* %s\n", __func__);
 
         assert_se(sd_radv_new(&ra) >= 0);
         assert_se(ra);
@@ -295,7 +295,7 @@ static void test_ra(void) {
         sd_radv *ra;
         unsigned i;
 
-        printf("* %s\n", __FUNCTION__);
+        printf("* %s\n", __func__);
 
         assert_se(socketpair(AF_UNIX, SOCK_SEQPACKET | SOCK_CLOEXEC | SOCK_NONBLOCK, 0, test_fd) >= 0);
 
index 5e50453c35fafa62ee78de495e60040b5b6b133c..ae26ee7e741cdd2510666eacc9a5bcc522b955a7 100644 (file)
@@ -273,7 +273,7 @@ static void test_rs(void) {
         sd_ndisc *nd;
 
         if (verbose)
-                printf("* %s\n", __FUNCTION__);
+                printf("* %s\n", __func__);
 
         send_ra_function = send_ra;
 
@@ -366,7 +366,7 @@ static void test_timeout(void) {
         sd_ndisc *nd;
 
         if (verbose)
-                printf("* %s\n", __FUNCTION__);
+                printf("* %s\n", __func__);
 
         send_ra_function = test_timeout_value;
 
index 43f9a7bdaadadd3c6aa489bf9f9aa1ae35024403..61c5509e1c82c2911928d2486f7a864417ac9d12 100644 (file)
@@ -142,6 +142,7 @@ BUS_ERROR_MAP_ELF_REGISTER const sd_bus_error_map bus_common_errors[] = {
         SD_BUS_ERROR_MAP(BUS_ERROR_TOO_MANY_OPERATIONS,          ENOBUFS),
         SD_BUS_ERROR_MAP(BUS_ERROR_AUTHENTICATION_LIMIT_HIT,     ETOOMANYREFS),
         SD_BUS_ERROR_MAP(BUS_ERROR_HOME_CANT_AUTHENTICATE,       EKEYREVOKED),
+        SD_BUS_ERROR_MAP(BUS_ERROR_HOME_IN_USE,                  EADDRINUSE),
 
         SD_BUS_ERROR_MAP_END
 };
index fd8f0c240e96a5c8bfb410eb0bef6ef1f1960d18..348cd5094b3861d9790a8775e378ea44e71f8bb5 100644 (file)
 #define BUS_ERROR_TOO_MANY_OPERATIONS          "org.freedesktop.home1.TooManyOperations"
 #define BUS_ERROR_AUTHENTICATION_LIMIT_HIT     "org.freedesktop.home1.AuthenticationLimitHit"
 #define BUS_ERROR_HOME_CANT_AUTHENTICATE       "org.freedesktop.home1.HomeCantAuthenticate"
+#define BUS_ERROR_HOME_IN_USE                  "org.freedesktop.home1.HomeInUse"
 
 BUS_ERROR_MAP_ELF_USE(bus_common_errors);
index 954b159bf2e40a0eaacbcf9b348fb1933bc92d4b..96529b422be3ef71e4c926fda41d870d153d403a 100644 (file)
@@ -4636,7 +4636,7 @@ _public_ int sd_bus_message_skip(sd_bus_message *m, const char *types) {
                 if (r < 0)
                         return r;
 
-                types = strndupa(c->signature + c->index, l);
+                types = strndupa_safe(c->signature + c->index, l);
         }
 
         switch (*types) {
index bfd42aea7da6b50758dae330c35c2906f50d926e..bf69539062dfd1ef44274d08d39c3442cfce65b4 100644 (file)
@@ -1513,7 +1513,7 @@ static struct node *bus_node_allocate(sd_bus *bus, const char *path) {
                 e = strrchr(path, '/');
                 assert(e);
 
-                p = strndupa(path, MAX(1, e - path));
+                p = strndupa_safe(path, MAX(1, e - path));
 
                 parent = bus_node_allocate(bus, p);
                 if (!parent)
index 4b8d73c3e083c054542941e49c72c7032fa018e6..05c89f61bf091e70e7873b4bcd3ddcc43bba4492 100644 (file)
@@ -726,7 +726,8 @@ static int bus_socket_inotify_setup(sd_bus *b) {
         }
 
         /* Make sure the path is NUL terminated */
-        p = strndupa(b->sockaddr.un.sun_path, sizeof(b->sockaddr.un.sun_path));
+        p = strndupa_safe(b->sockaddr.un.sun_path,
+                          sizeof(b->sockaddr.un.sun_path));
 
         /* Make sure the path is absolute */
         r = path_make_absolute_cwd(p, &absolute);
index 80f2bdd87f370e750975c04781ee01309c213f61..96d5b9605e0db2da740104a2d5bd985d1499f97c 100644 (file)
@@ -249,6 +249,7 @@ _public_ int sd_bus_new(sd_bus **ret) {
                 .original_pid = getpid_cached(),
                 .n_groups = SIZE_MAX,
                 .close_on_exit = true,
+                .ucred = UCRED_INVALID,
         };
 
         /* We guarantee that wqueue always has space for at least one entry */
@@ -1406,7 +1407,7 @@ int bus_set_address_system_remote(sd_bus *b, const char *host) {
                 rbracket = strchr(host, ']');
                 if (!rbracket)
                         return -EINVAL;
-                t = strndupa(host + 1, rbracket - host - 1);
+                t = strndupa_safe(host + 1, rbracket - host - 1);
                 e = bus_address_escape(t);
                 if (!e)
                         return -ENOMEM;
@@ -1439,7 +1440,7 @@ int bus_set_address_system_remote(sd_bus *b, const char *host) {
 
                 t = strchr(p, '/');
                 if (t) {
-                        p = strndupa(p, t - p);
+                        p = strndupa_safe(p, t - p);
                         got_forward_slash = true;
                 }
 
@@ -1466,7 +1467,7 @@ interpret_port_as_machine_old_syntax:
         if (!e) {
                 char *t;
 
-                t = strndupa(host, strcspn(host, ":/"));
+                t = strndupa_safe(host, strcspn(host, ":/"));
 
                 e = bus_address_escape(t);
                 if (!e)
index b92558fea9d43ad5dbfac4e5fe85f3e007ea6642..59421094c566c3739e753ae4e914a81d5373c9b6 100644 (file)
@@ -16,7 +16,7 @@ static void test_one_address(sd_bus *b,
         r = bus_set_address_system_remote(b, host);
         log_info("\"%s\" â†’ %d, \"%s\"", host, r, strna(r >= 0 ? b->address : NULL));
         if (result < 0 || expected) {
-                assert(r == result);
+                assert_se(r == result);
                 if (r >= 0)
                         assert_se(streq(b->address, expected));
         }
index a71add4342e6ec67845113fc6d3ea07199450936..6c8d5db6933bb5b3ce063f3198a9be72e27a3ec8 100644 (file)
@@ -219,6 +219,19 @@ static int enumerator2_callback(sd_bus *bus, const char *path, void *userdata, c
         return 1;
 }
 
+static int enumerator3_callback(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error) {
+        _cleanup_strv_free_ char **v = NULL;
+
+        if (!object_path_startswith("/value/b", path))
+                return 1;
+
+        for (unsigned i = 0; i < 30; i++)
+                assert_se(strv_extendf(&v, "/value/b/%u", i) >= 0);
+
+        *nodes = TAKE_PTR(v);
+        return 1;
+}
+
 static void *server(void *p) {
         struct context *c = p;
         sd_bus *bus = NULL;
@@ -238,6 +251,7 @@ static void *server(void *p) {
         assert_se(sd_bus_add_fallback_vtable(bus, NULL, "/value", "org.freedesktop.systemd.ValueTest", vtable2, NULL, UINT_TO_PTR(20)) >= 0);
         assert_se(sd_bus_add_node_enumerator(bus, NULL, "/value", enumerator_callback, NULL) >= 0);
         assert_se(sd_bus_add_node_enumerator(bus, NULL, "/value/a", enumerator2_callback, NULL) >= 0);
+        assert_se(sd_bus_add_node_enumerator(bus, NULL, "/value/b", enumerator3_callback, NULL) >= 0);
         assert_se(sd_bus_add_object_manager(bus, NULL, "/value") >= 0);
         assert_se(sd_bus_add_object_manager(bus, NULL, "/value/a") >= 0);
 
@@ -280,6 +294,7 @@ static int client(struct context *c) {
         _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
         _cleanup_(sd_bus_unrefp) sd_bus *bus = NULL;
         _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
+        _cleanup_strv_free_ char **lines = NULL;
         const char *s;
         int r;
 
@@ -400,6 +415,30 @@ static int client(struct context *c) {
         assert_se(r >= 0);
         fputs(s, stdout);
 
+        assert_se(lines = strv_split_newlines(s));
+        assert_se(strv_contains(lines, " <node name=\"x\"/>"));
+        assert_se(strv_contains(lines, " <node name=\"y\"/>"));
+        assert_se(strv_contains(lines, " <node name=\"z\"/>"));
+        lines = strv_free(lines);
+
+        reply = sd_bus_message_unref(reply);
+
+        r = sd_bus_call_method(bus, "org.freedesktop.systemd.test", "/value/b", "org.freedesktop.DBus.Introspectable", "Introspect", &error, &reply, NULL);
+        assert_se(r >= 0);
+
+        r = sd_bus_message_read(reply, "s", &s);
+        assert_se(r >= 0);
+        fputs(s, stdout);
+
+        assert_se(lines = strv_split_newlines(s));
+        for (unsigned i = 0; i < 30; i++) {
+                _cleanup_free_ char *n = NULL;
+
+                assert_se(asprintf(&n, " <node name=\"%u\"/>", i) >= 0);
+                assert_se(strv_contains(lines, n));
+        }
+        lines = strv_free(lines);
+
         reply = sd_bus_message_unref(reply);
 
         r = sd_bus_call_method(bus, "org.freedesktop.systemd.test", "/foo", "org.freedesktop.DBus.Properties", "GetAll", &error, &reply, "s", NULL);
index b485e3e2b632aba145bd654b28b0316bcabaa307..a446c27583ef228a34e71e0acad531faffe46ff0 100644 (file)
@@ -143,7 +143,7 @@ int device_monitor_new_full(sd_device_monitor **ret, MonitorNetlinkGroup group,
         }
 
         if (fd < 0) {
-                sock = socket(PF_NETLINK, SOCK_RAW|SOCK_CLOEXEC|SOCK_NONBLOCK, NETLINK_KOBJECT_UEVENT);
+                sock = socket(AF_NETLINK, SOCK_RAW|SOCK_CLOEXEC|SOCK_NONBLOCK, NETLINK_KOBJECT_UEVENT);
                 if (sock < 0)
                         return log_debug_errno(errno, "sd-device-monitor: Failed to create socket: %m");
         }
@@ -178,7 +178,7 @@ int device_monitor_new_full(sd_device_monitor **ret, MonitorNetlinkGroup group,
 
                 netns = ioctl(m->sock, SIOCGSKNS);
                 if (netns < 0)
-                        log_debug_errno(errno, "sd-device-monitor: Unable to get network namespace of udev netlink socket, unable to determine if we are in host netns: %m");
+                        log_debug_errno(errno, "sd-device-monitor: Unable to get network namespace of udev netlink socket, unable to determine if we are in host netns, ignoring: %m");
                 else {
                         struct stat a, b;
 
@@ -191,9 +191,9 @@ int device_monitor_new_full(sd_device_monitor **ret, MonitorNetlinkGroup group,
                                 if (ERRNO_IS_PRIVILEGE(errno))
                                         /* If we can't access PID1's netns info due to permissions, it's fine, this is a
                                          * safety check only after all. */
-                                        log_debug_errno(errno, "sd-device-monitor: No permission to stat PID1's netns, unable to determine if we are in host netns: %m");
+                                        log_debug_errno(errno, "sd-device-monitor: No permission to stat PID1's netns, unable to determine if we are in host netns, ignoring: %m");
                                 else
-                                        log_debug_errno(errno, "sd-device-monitor: Failed to stat PID1's netns: %m");
+                                        log_debug_errno(errno, "sd-device-monitor: Failed to stat PID1's netns, ignoring: %m");
 
                         } else if (a.st_dev != b.st_dev || a.st_ino != b.st_ino)
                                 log_debug("sd-device-monitor: Netlink socket we listen on is not from host netns, we won't see device events.");
index 141e10a18ad2d6c16a0a19873868be372898cca0..e594d5fbe4e1babe38f079fe38dfdd986d591612 100644 (file)
@@ -369,7 +369,7 @@ _public_ int sd_device_new_from_subsystem_sysname(
         }
 
         /* translate sysname back to sysfs filename */
-        name = strdupa(sysname);
+        name = strdupa_safe(sysname);
         for (size_t i = 0; name[i]; i++)
                 if (name[i] == '/')
                         name[i] = '!';
index e28885b5e06c6931ef899b73f1e2dd9da380fc9a..406d10d92b43bf0d2db94d7657a3453c6b05e6db 100644 (file)
@@ -404,8 +404,8 @@ struct inotify_context {
 static void maybe_exit(sd_event_source *s, struct inotify_context *c) {
         unsigned n;
 
-        assert(s);
-        assert(c);
+        assert_se(s);
+        assert_se(c);
 
         if (!c->delete_self_handler_called)
                 return;
index 0bfe9f7f477e16a0ed577f2161b201b1a0c9bf87..0ff25c1f4729bf6462e7252f93e799501427e72b 100644 (file)
@@ -182,14 +182,13 @@ int journal_file_fsprg_seek(JournalFile *f, uint64_t goal) {
         } else {
                 f->fsprg_state_size = FSPRG_stateinbytes(FSPRG_RECOMMENDED_SECPAR);
                 f->fsprg_state = malloc(f->fsprg_state_size);
-
                 if (!f->fsprg_state)
                         return -ENOMEM;
         }
 
         log_debug("Seeking FSPRG key to %"PRIu64".", goal);
 
-        msk = alloca(FSPRG_mskinbytes(FSPRG_RECOMMENDED_SECPAR));
+        msk = alloca_safe(FSPRG_mskinbytes(FSPRG_RECOMMENDED_SECPAR));
         FSPRG_GenMK(msk, NULL, f->fsprg_seed, f->fsprg_seed_size, FSPRG_RECOMMENDED_SECPAR);
         FSPRG_Seek(f->fsprg_state, goal, msk, f->fsprg_seed, f->fsprg_seed_size);
         return 0;
index 9f8b02d89b166f72719654c23f8b2d1ef4386231..b4052ad417bfc4f96bd769aa13ad76599b6cbf3c 100644 (file)
@@ -2146,8 +2146,7 @@ int journal_file_append_entry(
                 return r;
 #endif
 
-        /* alloca() can't take 0, hence let's allocate at least one */
-        items = newa(EntryItem, MAX(1u, n_iovec));
+        items = newa(EntryItem, n_iovec);
 
         for (unsigned i = 0; i < n_iovec; i++) {
                 uint64_t p;
@@ -3873,8 +3872,7 @@ int journal_file_copy_entry(JournalFile *from, JournalFile *to, Object *o, uint6
         boot_id = &o->entry.boot_id;
 
         n = journal_file_entry_n_items(o);
-        /* alloca() can't take 0, hence let's allocate at least one */
-        items = newa(EntryItem, MAX(1u, n));
+        items = newa(EntryItem, n);
 
         for (uint64_t i = 0; i < n; i++) {
                 uint64_t l, h;
index fd3fd7ef9c944060cb565f7454e832181ccd4282..421782515631793cb6d1d0c61783b287bb24395d 100644 (file)
@@ -96,7 +96,7 @@ _public_ int sd_journal_printv(int priority, const char *format, va_list ap) {
 
         /* Allocate large buffer to accommodate big message */
         if (len >= LINE_MAX) {
-                buffer = alloca(len + 9);
+                buffer = alloca_safe(len + 9);
                 memcpy(buffer, "MESSAGE=", 8);
                 assert_se(vsnprintf(buffer + 8, len + 1, format, ap) == len);
         }
@@ -472,7 +472,7 @@ _public_ int sd_journal_printv_with_location(int priority, const char *file, con
 
         /* Allocate large buffer to accommodate big message */
         if (len >= LINE_MAX) {
-                buffer = alloca(len + 9);
+                buffer = alloca_safe(len + 9);
                 memcpy(buffer, "MESSAGE=", 8);
                 assert_se(vsnprintf(buffer + 8, len + 1, format, ap) == len);
         }
index 8b7415f0db47c933824071caee725be3688886af..fa9f420e06001f275b245c6f4aed3b96460fa0ec 100644 (file)
@@ -1468,7 +1468,7 @@ static int dirname_is_machine_id(const char *fn) {
                 if (!log_namespace_name_valid(e + 1))
                         return false;
 
-                k = strndupa(fn, e - fn);
+                k = strndupa_safe(fn, e - fn);
                 r = sd_id128_from_string(k, &id);
         } else
                 r = sd_id128_from_string(fn, &id);
@@ -1493,7 +1493,7 @@ static int dirname_has_namespace(const char *fn, const char *namespace) {
                 if (!streq(e + 1, namespace))
                         return false;
 
-                k = strndupa(fn, e - fn);
+                k = strndupa_safe(fn, e - fn);
                 return id128_is_valid(k);
         }
 
@@ -1530,7 +1530,7 @@ static bool dirent_is_journal_subdir(const struct dirent *de) {
         if (!e)
                 return id128_is_valid(de->d_name); /* No namespace */
 
-        n = strndupa(de->d_name, e - de->d_name);
+        n = strndupa_safe(de->d_name, e - de->d_name);
         if (!id128_is_valid(n))
                 return false;
 
index 54e0e738b3b645e0f13b3ab1496996de0767a4ca..615bbb2934604c603dbe42ce0aa2b625560409a8 100644 (file)
@@ -118,7 +118,7 @@ _unused_ static void test_decompress_startswith(const char *compression,
                 compressed = compressed2 = malloc(BUFSIZE_2);
                 assert_se(compressed2);
                 r = compress(data, data_len, compressed, BUFSIZE_2, &csize);
-                assert(r == 0);
+                assert_se(r == 0);
         }
         assert_se(r == 0);
 
index d127443c4c0f9b8518743c91c1965b1cae1c131b..4a35e6142579a9e96413c193b5d8632c6316b722 100644 (file)
@@ -136,7 +136,7 @@ _public_ int sd_pid_get_cgroup(pid_t pid, char **cgroup) {
 }
 
 _public_ int sd_peer_get_session(int fd, char **session) {
-        struct ucred ucred = {};
+        struct ucred ucred = UCRED_INVALID;
         int r;
 
         assert_return(fd >= 0, -EBADF);
index 718073bb8fea2601371321265e1f10b59f679d51..888b5bcf35849514ccdf66829d557e9c0171857e 100644 (file)
@@ -20,7 +20,7 @@
 int socket_open(int family) {
         int fd;
 
-        fd = socket(PF_NETLINK, SOCK_RAW|SOCK_CLOEXEC|SOCK_NONBLOCK, family);
+        fd = socket(AF_NETLINK, SOCK_RAW|SOCK_CLOEXEC|SOCK_NONBLOCK, family);
         if (fd < 0)
                 return -errno;
 
index c5a5e512a203f1c2d2f2254a5d517d06ea9aeb2f..fbc3ef06094fb342198d3b0462add1ff2654e364 100644 (file)
@@ -287,7 +287,7 @@ struct test_async_object {
 };
 
 static struct test_async_object *test_async_object_free(struct test_async_object *t) {
-        assert(t);
+        assert_se(t);
 
         free(t->ifname);
         return mfree(t);
@@ -315,7 +315,7 @@ static int link_handler2(sd_netlink *rtnl, sd_netlink_message *m, void *userdata
 static void test_async_object_destroy(void *userdata) {
         struct test_async_object *t = userdata;
 
-        assert(userdata);
+        assert_se(userdata);
 
         log_info("%s: n_ref=%u", __func__, t->n_ref);
         test_async_object_unref(t);
@@ -593,8 +593,8 @@ static int genl_ctrl_match_callback(sd_netlink *genl, sd_netlink_message *m, voi
         uint16_t id;
         uint8_t cmd;
 
-        assert(genl);
-        assert(m);
+        assert_se(genl);
+        assert_se(m);
 
         assert_se(sd_genl_message_get_family_name(genl, m, &name) >= 0);
         assert_se(streq(name, CTRL_GENL_NAME));
index 32af23d6924187d19add02b32402767237595421..1bd8f5c0ae64a97029d984e7d6dbf9b3e04588c5 100644 (file)
@@ -648,9 +648,10 @@ int find_legacy_keymap(Context *c, char **ret) {
                  */
                 char *l, *v = NULL, *converted;
 
-                l = strndupa(c->x11_layout, strcspn(c->x11_layout, ","));
+                l = strndupa_safe(c->x11_layout, strcspn(c->x11_layout, ","));
                 if (c->x11_variant)
-                        v = strndupa(c->x11_variant, strcspn(c->x11_variant, ","));
+                        v = strndupa_safe(c->x11_variant,
+                                          strcspn(c->x11_variant, ","));
                 r = find_converted_keymap(l, v, &converted);
                 if (r < 0)
                         return r;
index df0eb030d46651339fc35c11c0b61949b29e187e..c228385d0efd1fb1377c0522d314f063362eb7d0 100644 (file)
@@ -560,7 +560,7 @@ static void log_xkb(struct xkb_context *ctx, enum xkb_log_level lvl, const char
 
         fmt = strjoina("libxkbcommon: ", format);
         DISABLE_WARNING_FORMAT_NONLITERAL;
-        log_internalv(LOG_DEBUG, 0, __FILE__, __LINE__, __func__, fmt, args);
+        log_internalv(LOG_DEBUG, 0, PROJECT_FILE, __LINE__, __func__, fmt, args);
         REENABLE_WARNING;
 }
 
index 0022a980c52655d8c562911a1e66e59df374a203..4fa5fe5452e681e07bfc4412c8507e97ed83e3e8 100644 (file)
@@ -929,7 +929,7 @@ int bus_machine_method_copy(sd_bus_message *message, void *userdata, sd_bus_erro
         host_basename = basename(host_path);
 
         container_basename = basename(container_path);
-        t = strdupa(container_path);
+        t = strdupa_safe(container_path);
         container_dirname = dirname(t);
 
         hostfd = open_parent(host_path, O_CLOEXEC, 0);
index 60e074e99bfe13bc8c3cbcd837494025ccbe947a..c07b269f36419e2c4ed6f6da1ec5e460211ecaa6 100644 (file)
@@ -475,7 +475,7 @@ static int parse_cmdline_ip_mtu_mac(Context *context, const char *ifname, int fa
         if (!p)
                 mtu = value;
         else
-                mtu = strndupa(value, p - value);
+                mtu = strndupa_safe(value, p - value);
 
         r = network_set_mtu(context, ifname, family, mtu);
         if (r < 0)
@@ -511,14 +511,14 @@ static int parse_ip_address_one(int family, const char **value, union in_addr_un
                 if (q[1] != ':')
                         return -EINVAL;
 
-                buf = strndupa(p + 1, q - p - 1);
+                buf = strndupa_safe(p + 1, q - p - 1);
                 p = q + 2;
         } else {
                 q = strchr(p, ':');
                 if (!q)
                         return -EINVAL;
 
-                buf = strndupa(p, q - p);
+                buf = strndupa_safe(p, q - p);
                 p = q + 1;
         }
 
@@ -549,7 +549,7 @@ static int parse_netmask_or_prefixlen(int family, const char **value, unsigned c
                 if (!p)
                         return -EINVAL;
 
-                q = strndupa(*value, p - *value);
+                q = strndupa_safe(*value, p - *value);
                 r = safe_atou8(q, ret);
                 if (r < 0)
                         return r;
@@ -588,7 +588,7 @@ static int parse_cmdline_ip_address(Context *context, int family, const char *va
                 return -EINVAL;
 
         if (p != value) {
-                hostname = strndupa(value, p - value);
+                hostname = strndupa_safe(value, p - value);
                 if (!hostname_is_valid(hostname, 0))
                         return -EINVAL;
         }
@@ -600,7 +600,7 @@ static int parse_cmdline_ip_address(Context *context, int family, const char *va
         if (!p)
                 return -EINVAL;
 
-        ifname = strndupa(value, p - value);
+        ifname = strndupa_safe(value, p - value);
 
         value = p + 1;
 
@@ -609,7 +609,7 @@ static int parse_cmdline_ip_address(Context *context, int family, const char *va
         if (!p)
                 dhcp_type = value;
         else
-                dhcp_type = strndupa(value, p - value);
+                dhcp_type = strndupa_safe(value, p - value);
 
         r = network_set_dhcp_type(context, ifname, dhcp_type);
         if (r < 0)
@@ -644,7 +644,7 @@ static int parse_cmdline_ip_address(Context *context, int family, const char *va
                 if (r < 0)
                         return r;
         } else {
-                dns = strndupa(value, p - value);
+                dns = strndupa_safe(value, p - value);
                 r = network_set_dns(context, ifname, dns);
                 if (r < 0)
                         return r;
@@ -666,14 +666,14 @@ static int parse_cmdline_ip_interface(Context *context, const char *value) {
         if (!p)
                 return -EINVAL;
 
-        ifname = strndupa(value, p - value);
+        ifname = strndupa_safe(value, p - value);
 
         value = p + 1;
         p = strchr(value, ':');
         if (!p)
                 dhcp_type = value;
         else
-                dhcp_type = strndupa(value, p - value);
+                dhcp_type = strndupa_safe(value, p - value);
 
         r = network_set_dhcp_type(context, ifname, dhcp_type);
         if (r < 0)
@@ -726,7 +726,7 @@ static int parse_cmdline_rd_route(Context *context, const char *key, const char
                 if (p[1] != ':')
                         return -EINVAL;
 
-                buf = strndupa(value + 1, p - value - 1);
+                buf = strndupa_safe(value + 1, p - value - 1);
                 value = p + 2;
                 family = AF_INET6;
         } else {
@@ -734,7 +734,7 @@ static int parse_cmdline_rd_route(Context *context, const char *key, const char
                 if (!p)
                         return -EINVAL;
 
-                buf = strndupa(value, p - value);
+                buf = strndupa_safe(value, p - value);
                 value = p + 1;
                 family = AF_INET;
         }
@@ -786,7 +786,7 @@ static int parse_cmdline_vlan(Context *context, const char *key, const char *val
         if (!p)
                 return -EINVAL;
 
-        name = strndupa(value, p - value);
+        name = strndupa_safe(value, p - value);
 
         netdev = netdev_get(context, name);
         if (!netdev) {
@@ -810,7 +810,7 @@ static int parse_cmdline_bridge(Context *context, const char *key, const char *v
         if (!p)
                 return -EINVAL;
 
-        name = strndupa(value, p - value);
+        name = strndupa_safe(value, p - value);
 
         netdev = netdev_get(context, name);
         if (!netdev) {
@@ -848,7 +848,7 @@ static int parse_cmdline_bond(Context *context, const char *key, const char *val
         if (!p)
                 return -EINVAL;
 
-        name = strndupa(value, p - value);
+        name = strndupa_safe(value, p - value);
 
         netdev = netdev_get(context, name);
         if (!netdev) {
@@ -862,7 +862,7 @@ static int parse_cmdline_bond(Context *context, const char *key, const char *val
         if (!p)
                 slaves = value;
         else
-                slaves = strndupa(value, p - value);
+                slaves = strndupa_safe(value, p - value);
 
         if (isempty(slaves))
                 return -EINVAL;
@@ -907,7 +907,7 @@ static int parse_cmdline_ifname(Context *context, const char *key, const char *v
         if (!p)
                 return -EINVAL;
 
-        name = strndupa(value, p - value);
+        name = strndupa_safe(value, p - value);
 
         r = ether_addr_from_string(p + 1, &mac);
         if (r < 0)
index 8827d33c2a671b1b1a7c1fef1bef2711f6b17bd8..6ec178f35404f9a0fff70e8b3199af520c277d48 100644 (file)
@@ -56,64 +56,62 @@ static bool dhcp6_lease_has_pd_prefix(sd_dhcp6_lease *lease) {
         return sd_dhcp6_lease_get_pd(lease, &pd_prefix, &pd_prefix_len, &lifetime_preferred, &lifetime_valid) >= 0;
 }
 
-static int dhcp6_pd_get_link_by_prefix(Manager *manager, const struct in6_addr *prefix, Link **ret) {
-        union in_addr_union u;
-        Link *link;
+static void link_remove_dhcp6_pd_prefix(Link *link, const struct in6_addr *prefix) {
+        void *key;
 
-        assert(manager);
+        assert(link);
+        assert(link->manager);
         assert(prefix);
 
-        u.in6 = *prefix;
+        if (hashmap_get(link->manager->links_by_dhcp6_pd_prefix, prefix) != link)
+                return;
 
-        HASHMAP_FOREACH(link, manager->links_by_index) {
-                if (!link_dhcp6_pd_is_enabled(link))
-                        continue;
+        hashmap_remove2(link->manager->links_by_dhcp6_pd_prefix, prefix, &key);
+        free(key);
+}
+
+static int link_add_dhcp6_pd_prefix(Link *link, const struct in6_addr *prefix) {
+        _cleanup_free_ struct in6_addr *copy = NULL;
+        int r;
 
-                if (link->network->dhcp6_pd_assign) {
-                        Address *address;
+        assert(link);
+        assert(prefix);
 
-                        SET_FOREACH(address, link->addresses) {
-                                if (address->source != NETWORK_CONFIG_SOURCE_DHCP6PD)
-                                        continue;
-                                assert(address->family == AF_INET6);
+        copy = newdup(struct in6_addr, prefix, 1);
+        if (!copy)
+                return -ENOMEM;
 
-                                if (in_addr_prefix_covers(AF_INET6, &u, 64, &address->in_addr) > 0) {
-                                        if (ret)
-                                                *ret = link;
-                                        return 0;
-                                }
-                        }
-                } else {
-                        Route *route;
-
-                        SET_FOREACH(route, link->routes) {
-                                if (route->source != NETWORK_CONFIG_SOURCE_DHCP6PD)
-                                        continue;
-                                assert(route->family == AF_INET6);
-
-                                if (in6_addr_equal(&route->dst.in6, prefix)) {
-                                        if (ret)
-                                                *ret = link;
-                                        return 0;
-                                }
-                        }
-                }
-        }
+        r = hashmap_ensure_put(&link->manager->links_by_dhcp6_pd_prefix, &in6_addr_hash_ops_free, copy, link);
+        if (r < 0)
+                return r;
+        if (r > 0)
+                TAKE_PTR(copy);
 
-        return -ENOENT;
+        return 0;
 }
 
-static int dhcp6_pd_get_assigned_prefix(Link *link, const struct in6_addr *pd_prefix, uint8_t pd_prefix_len, struct in6_addr *ret) {
-        union in_addr_union u;
+static int link_get_by_dhcp6_pd_prefix(Manager *manager, const struct in6_addr *prefix, Link **ret) {
+        Link *link;
+
+        assert(manager);
+        assert(prefix);
+
+        link = hashmap_get(manager->links_by_dhcp6_pd_prefix, prefix);
+        if (!link)
+                return -ENODEV;
 
+        if (ret)
+                *ret = link;
+        return 0;
+}
+
+static int dhcp6_pd_get_assigned_prefix(Link *link, const struct in6_addr *pd_prefix, uint8_t pd_prefix_len, struct in6_addr *ret) {
         assert(link);
         assert(pd_prefix);
 
         if (!link_dhcp6_pd_is_enabled(link))
                 return -ENOENT;
 
-        u.in6 = *pd_prefix;
-
         if (link->network->dhcp6_pd_assign) {
                 Address *address;
 
@@ -122,14 +120,14 @@ static int dhcp6_pd_get_assigned_prefix(Link *link, const struct in6_addr *pd_pr
                                 continue;
                         assert(address->family == AF_INET6);
 
-                        if (in_addr_prefix_covers(AF_INET6, &u, pd_prefix_len, &address->in_addr) <= 0)
+                        if (in6_addr_prefix_covers(pd_prefix, pd_prefix_len, &address->in_addr.in6) <= 0)
                                 continue;
 
                         if (ret) {
-                                union in_addr_union prefix = address->in_addr;
+                                struct in6_addr prefix = address->in_addr.in6;
 
-                                in_addr_mask(AF_INET6, &prefix, 64);
-                                *ret = prefix.in6;
+                                in6_addr_mask(&prefix, 64);
+                                *ret = prefix;
                         }
                         return 0;
                 }
@@ -141,7 +139,7 @@ static int dhcp6_pd_get_assigned_prefix(Link *link, const struct in6_addr *pd_pr
                                 continue;
                         assert(route->family == AF_INET6);
 
-                        if (in_addr_prefix_covers(AF_INET6, &u, pd_prefix_len, &route->dst) > 0) {
+                        if (in6_addr_prefix_covers(pd_prefix, pd_prefix_len, &route->dst.in6) > 0) {
                                 if (ret)
                                         *ret = route->dst.in6;
                                 return 0;
@@ -175,6 +173,8 @@ int dhcp6_pd_remove(Link *link, bool only_marked) {
                 if (link->radv)
                         (void) sd_radv_remove_prefix(link->radv, &route->dst.in6, 64);
 
+                link_remove_dhcp6_pd_prefix(link, &route->dst.in6);
+
                 k = route_remove(route);
                 if (k < 0)
                         r = k;
@@ -183,17 +183,20 @@ int dhcp6_pd_remove(Link *link, bool only_marked) {
         }
 
         SET_FOREACH(address, link->addresses) {
+                struct in6_addr prefix;
+
                 if (address->source != NETWORK_CONFIG_SOURCE_DHCP6PD)
                         continue;
                 if (only_marked && !address_is_marked(address))
                         continue;
 
-                if (link->radv) {
-                        union in_addr_union prefix = address->in_addr;
+                prefix = address->in_addr.in6;
+                in6_addr_mask(&prefix, 64);
 
-                        in_addr_mask(AF_INET6, &prefix, 64);
-                        (void) sd_radv_remove_prefix(link->radv, &prefix.in6, 64);
-                }
+                if (link->radv)
+                        (void) sd_radv_remove_prefix(link->radv, &prefix, 64);
+
+                link_remove_dhcp6_pd_prefix(link, &prefix);
 
                 k = address_remove(address);
                 if (k < 0)
@@ -221,33 +224,37 @@ static int dhcp6_pd_address_ready_callback(Address *address) {
 }
 
 static int dhcp6_pd_check_ready(Link *link) {
-        bool has_ready = false;
-        Address *address;
         int r;
 
         assert(link);
+        assert(link->network);
 
         if (link->dhcp6_pd_messages > 0) {
                 log_link_debug(link, "%s(): DHCPv6PD addresses and routes are not set.", __func__);
                 return 0;
         }
 
-        SET_FOREACH(address, link->addresses) {
-                if (address->source != NETWORK_CONFIG_SOURCE_DHCP6PD)
-                        continue;
-                if (address_is_ready(address)) {
-                        has_ready = true;
-                        break;
+        if (link->network->dhcp6_pd_assign) {
+                bool has_ready = false;
+                Address *address;
+
+                SET_FOREACH(address, link->addresses) {
+                        if (address->source != NETWORK_CONFIG_SOURCE_DHCP6PD)
+                                continue;
+                        if (address_is_ready(address)) {
+                                has_ready = true;
+                                break;
+                        }
                 }
-        }
 
-        if (!has_ready) {
-                SET_FOREACH(address, link->addresses)
-                        if (address->source == NETWORK_CONFIG_SOURCE_DHCP6PD)
-                                address->callback = dhcp6_pd_address_ready_callback;
+                if (!has_ready) {
+                        SET_FOREACH(address, link->addresses)
+                                if (address->source == NETWORK_CONFIG_SOURCE_DHCP6PD)
+                                        address->callback = dhcp6_pd_address_ready_callback;
 
-                log_link_debug(link, "%s(): no DHCPv6PD address is ready.", __func__);
-                return 0;
+                        log_link_debug(link, "%s(): no DHCPv6PD address is ready.", __func__);
+                        return 0;
+                }
         }
 
         link->dhcp6_pd_configured = true;
@@ -436,7 +443,7 @@ static int dhcp6_pd_assign_prefix(
         if (r < 0)
                 return r;
 
-        return 0;
+        return link_add_dhcp6_pd_prefix(link, prefix);
 }
 
 static bool link_has_preferred_subnet_id(Link *link) {
@@ -483,9 +490,9 @@ static int dhcp6_get_preferred_delegated_prefix(
 
                 /* Verify that the prefix we did calculate fits in the pd prefix.
                  * This should not fail as we checked the prefix size beforehand */
-                assert_se(in_addr_prefix_covers(AF_INET6, (const union in_addr_union*) pd_prefix, pd_prefix_len, &prefix) > 0);
+                assert_se(in6_addr_prefix_covers(pd_prefix, pd_prefix_len, &prefix.in6) > 0);
 
-                if (dhcp6_pd_get_link_by_prefix(link->manager, &prefix.in6, &assigned_link) >= 0 &&
+                if (link_get_by_dhcp6_pd_prefix(link->manager, &prefix.in6, &assigned_link) >= 0 &&
                     assigned_link != link) {
                         _cleanup_free_ char *assigned_buf = NULL;
 
@@ -502,7 +509,7 @@ static int dhcp6_get_preferred_delegated_prefix(
         for (uint64_t n = 0; n < n_prefixes; n++) {
                 /* If we do not have an allocation preference just iterate
                  * through the address space and return the first free prefix. */
-                if (dhcp6_pd_get_link_by_prefix(link->manager, &prefix.in6, &assigned_link) < 0 ||
+                if (link_get_by_dhcp6_pd_prefix(link->manager, &prefix.in6, &assigned_link) < 0 ||
                     assigned_link == link) {
                         *ret = prefix.in6;
                         return 0;
@@ -516,12 +523,13 @@ static int dhcp6_get_preferred_delegated_prefix(
         return log_link_warning_errno(link, SYNTHETIC_ERRNO(ERANGE), "Couldn't find a suitable prefix. Ran out of address space.");
 }
 
-static void dhcp6_pd_prefix_distribute(Link *dhcp6_link,
-                                      const struct in6_addr *pd_prefix,
-                                      uint8_t pd_prefix_len,
-                                      uint32_t lifetime_preferred,
-                                      uint32_t lifetime_valid,
-                                      bool assign_preferred_subnet_id) {
+static int dhcp6_pd_prefix_distribute(
+                Link *dhcp6_link,
+                const struct in6_addr *pd_prefix,
+                uint8_t pd_prefix_len,
+                uint32_t lifetime_preferred,
+                uint32_t lifetime_valid,
+                bool assign_preferred_subnet_id) {
 
         Link *link;
         int r;
@@ -532,13 +540,13 @@ static void dhcp6_pd_prefix_distribute(Link *dhcp6_link,
         assert(pd_prefix_len <= 64);
 
         HASHMAP_FOREACH(link, dhcp6_link->manager->links_by_index) {
-                _cleanup_free_ char *assigned_buf = NULL;
+                _cleanup_free_ char *buf = NULL;
                 struct in6_addr assigned_prefix;
 
-                if (link == dhcp6_link)
+                if (!link_dhcp6_pd_is_enabled(link))
                         continue;
 
-                if (!link_dhcp6_pd_is_enabled(link))
+                if (link == dhcp6_link && !link->network->dhcp6_pd_assign)
                         continue;
 
                 if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
@@ -547,22 +555,25 @@ static void dhcp6_pd_prefix_distribute(Link *dhcp6_link,
                 if (assign_preferred_subnet_id != link_has_preferred_subnet_id(link))
                         continue;
 
-                r = dhcp6_pd_get_assigned_prefix(link, pd_prefix, pd_prefix_len, &assigned_prefix);
-                if (r < 0) {
-                        r = dhcp6_get_preferred_delegated_prefix(link, pd_prefix, pd_prefix_len, &assigned_prefix);
-                        if (r < 0)
-                                continue;
-                }
+                if (dhcp6_pd_get_assigned_prefix(link, pd_prefix, pd_prefix_len, &assigned_prefix) < 0 &&
+                    dhcp6_get_preferred_delegated_prefix(link, pd_prefix, pd_prefix_len, &assigned_prefix) < 0)
+                        continue;
 
-                (void) in6_addr_to_string(&assigned_prefix, &assigned_buf);
+                (void) in6_addr_prefix_to_string(&assigned_prefix, 64, &buf);
                 r = dhcp6_pd_assign_prefix(link, &assigned_prefix, lifetime_preferred, lifetime_valid);
                 if (r < 0) {
-                        log_link_error_errno(link, r, "Unable to assign/update prefix %s/64: %m",
-                                             strna(assigned_buf));
+                        log_link_warning_errno(link, r, "Failed to assign/update prefix %s: %m", strna(buf));
+                        if (link == dhcp6_link)
+                                return r;
+
                         link_enter_failed(link);
-                } else
-                        log_link_debug(link, "Assigned prefix %s/64", strna(assigned_buf));
+                        continue;
+                }
+
+                log_link_debug(link, "Assigned prefix %s", strna(buf));
         }
+
+        return 0;
 }
 
 static int dhcp6_pd_prepare(Link *link) {
@@ -833,7 +844,6 @@ static int dhcp6_pd_prefix_acquired(Link *dhcp6_link) {
         for (sd_dhcp6_lease_reset_pd_prefix_iter(dhcp6_link->dhcp6_lease);;) {
                 uint32_t lifetime_preferred, lifetime_valid;
                 struct in6_addr pd_prefix;
-                union in_addr_union prefix;
                 uint8_t pd_prefix_len;
 
                 r = sd_dhcp6_lease_get_pd(dhcp6_link->dhcp6_lease, &pd_prefix, &pd_prefix_len,
@@ -862,8 +872,8 @@ static int dhcp6_pd_prefix_acquired(Link *dhcp6_link) {
 
                 assert(pd_prefix_len <= 64);
 
-                prefix.in6 = pd_prefix;
-                r = in_addr_mask(AF_INET6, &prefix, pd_prefix_len);
+                /* Mask prefix for safety. */
+                r = in6_addr_mask(&pd_prefix, pd_prefix_len);
                 if (r < 0)
                         return log_link_error_errno(dhcp6_link, r, "Failed to mask DHCPv6 PD prefix: %m");
 
@@ -871,24 +881,28 @@ static int dhcp6_pd_prefix_acquired(Link *dhcp6_link) {
                         uint64_t n_prefixes = UINT64_C(1) << (64 - pd_prefix_len);
                         _cleanup_free_ char *buf = NULL;
 
-                        (void) in6_addr_prefix_to_string(&prefix.in6, pd_prefix_len, &buf);
+                        (void) in6_addr_prefix_to_string(&pd_prefix, pd_prefix_len, &buf);
                         log_link_debug(dhcp6_link, "Assigning up to %" PRIu64 " prefixes from %s",
                                        n_prefixes, strna(buf));
                 }
 
-                dhcp6_pd_prefix_distribute(dhcp6_link,
-                                           &prefix.in6,
-                                           pd_prefix_len,
-                                           lifetime_preferred,
-                                           lifetime_valid,
-                                           true);
-
-                dhcp6_pd_prefix_distribute(dhcp6_link,
-                                           &prefix.in6,
-                                           pd_prefix_len,
-                                           lifetime_preferred,
-                                           lifetime_valid,
-                                           false);
+                r = dhcp6_pd_prefix_distribute(dhcp6_link,
+                                               &pd_prefix,
+                                               pd_prefix_len,
+                                               lifetime_preferred,
+                                               lifetime_valid,
+                                               true);
+                if (r < 0)
+                        return r;
+
+                r = dhcp6_pd_prefix_distribute(dhcp6_link,
+                                               &pd_prefix,
+                                               pd_prefix_len,
+                                               lifetime_preferred,
+                                               lifetime_valid,
+                                               false);
+                if (r < 0)
+                        return r;
         }
 
         HASHMAP_FOREACH(link, dhcp6_link->manager->links_by_index) {
@@ -1445,12 +1459,6 @@ static int dhcp6_configure(Link *link) {
         if (r < 0)
                 return log_link_debug_errno(link, r, "DHCPv6 CLIENT: Failed to set ifindex: %m");
 
-        if (link->network->dhcp6_rapid_commit) {
-                r = sd_dhcp6_client_set_request_option(client, SD_DHCP6_OPTION_RAPID_COMMIT);
-                if (r < 0)
-                        return log_link_debug_errno(link, r, "DHCPv6 CLIENT: Failed to set request flag for rapid commit: %m");
-        }
-
         if (link->network->dhcp6_mudurl) {
                 r = sd_dhcp6_client_set_request_mud_url(client, link->network->dhcp6_mudurl);
                 if (r < 0)
index 7c02110796871a64170140684e7ebcb3749ee61f..3bc417e033ac580b3c81d3b91795d07fb92efdf6 100644 (file)
@@ -486,8 +486,11 @@ void link_check_ready(Link *link) {
                 if (!address_exists(a))
                         continue;
                 if (IN_SET(a->source,
-                           NETWORK_CONFIG_SOURCE_IPV4LL, NETWORK_CONFIG_SOURCE_DHCP4,
-                           NETWORK_CONFIG_SOURCE_DHCP6, NETWORK_CONFIG_SOURCE_NDISC)) {
+                           NETWORK_CONFIG_SOURCE_IPV4LL,
+                           NETWORK_CONFIG_SOURCE_DHCP4,
+                           NETWORK_CONFIG_SOURCE_DHCP6,
+                           NETWORK_CONFIG_SOURCE_DHCP6PD,
+                           NETWORK_CONFIG_SOURCE_NDISC)) {
                         has_dynamic_address = true;
                         break;
                 }
@@ -496,7 +499,7 @@ void link_check_ready(Link *link) {
         if ((link_ipv4ll_enabled(link) || link_dhcp4_enabled(link) || link_dhcp6_with_address_enabled(link) ||
              (link_dhcp6_pd_is_enabled(link) && link->network->dhcp6_pd_assign)) && !has_dynamic_address)
                 /* When DHCP[46] or IPv4LL is enabled, at least one address is acquired by them. */
-                return (void) log_link_debug(link, "%s(): DHCPv4, DHCPv6 or IPv4LL is enabled but no dynamic address is assigned yet.", __func__);
+                return (void) log_link_debug(link, "%s(): DHCPv4, DHCPv6, DHCPv6PD or IPv4LL is enabled but no dynamic address is assigned yet.", __func__);
 
         /* Ignore NDisc when ConfigureWithoutCarrier= is enabled, as IPv6AcceptRA= is enabled by default. */
         if (link_ipv4ll_enabled(link) || link_dhcp4_enabled(link) ||
index b4494d51827f1dc5af8045bad11c9b472f1aeda5..c5ccfb4b580da74a5fca5bca87e7d020d5db5d1a 100644 (file)
@@ -485,6 +485,7 @@ Manager* manager_free(Manager *m) {
         m->dirty_links = set_free_with_destructor(m->dirty_links, link_unref);
         m->links_by_name = hashmap_free(m->links_by_name);
         m->links_by_hw_addr = hashmap_free(m->links_by_hw_addr);
+        m->links_by_dhcp6_pd_prefix = hashmap_free(m->links_by_dhcp6_pd_prefix);
         m->links_by_index = hashmap_free_with_destructor(m->links_by_index, link_unref);
 
         m->networks = ordered_hashmap_free_with_destructor(m->networks, network_unref);
index 5f3f81ad9dcbc8ef325be0ac26d976fb8c14910e..42b77ee0f5c5c1a478410de1a8005ef9660aee1a 100644 (file)
@@ -48,6 +48,7 @@ struct Manager {
         Hashmap *links_by_index;
         Hashmap *links_by_name;
         Hashmap *links_by_hw_addr;
+        Hashmap *links_by_dhcp6_pd_prefix;
         Hashmap *netdevs;
         OrderedHashmap *networks;
         OrderedSet *address_pools;
index b2b1484a2e46648ff54bed2550701c3186f6878b..b8d1045f1a0d6e8765e8ea056e6c10b8388a6252 100644 (file)
@@ -543,7 +543,7 @@ int manager_rtnl_process_neighbor(sd_netlink *rtnl, sd_netlink_message *message,
         case RTM_NEWNEIGH:
                 if (neighbor) {
                         neighbor_enter_configured(neighbor);
-                        log_neighbor_debug(tmp, "Received remembered", link);
+                        log_neighbor_debug(neighbor, "Received remembered", link);
                 } else {
                         neighbor_enter_configured(tmp);
                         log_neighbor_debug(tmp, "Remembering", link);
index b670038d2ae43d9ce5451b45c1eb8aa3f12ccd54..2a75a98bee816ab9696900d233c5c261913e6c5d 100644 (file)
@@ -242,7 +242,6 @@ DHCPv6.UseDNS,                               config_parse_dhcp_use_dns,
 DHCPv6.UseHostname,                          config_parse_bool,                                        0,                             offsetof(Network, dhcp6_use_hostname)
 DHCPv6.UseDomains,                           config_parse_dhcp_use_domains,                            AF_INET6,                      0
 DHCPv6.UseNTP,                               config_parse_dhcp_use_ntp,                                AF_INET6,                      0
-DHCPv6.RapidCommit,                          config_parse_bool,                                        0,                             offsetof(Network, dhcp6_rapid_commit)
 DHCPv6.MUDURL,                               config_parse_mud_url,                                     0,                             offsetof(Network, dhcp6_mudurl)
 DHCPv6.RequestOptions,                       config_parse_dhcp_request_options,                        AF_INET6,                      0
 DHCPv6.UserClass,                            config_parse_dhcp_user_or_vendor_class,                   AF_INET6,                      offsetof(Network, dhcp6_user_class)
@@ -342,11 +341,11 @@ IPv6SendRA.Domains,                          config_parse_radv_search_domains,
 IPv6SendRA.DNSLifetimeSec,                   config_parse_sec,                                         0,                             offsetof(Network, router_dns_lifetime_usec)
 IPv6SendRA.UplinkInterface,                  config_parse_uplink,                                      0,                             0
 IPv6Prefix.Prefix,                           config_parse_prefix,                                      0,                             0
-IPv6Prefix.OnLink,                           config_parse_prefix_flags,                                0,                             0
-IPv6Prefix.AddressAutoconfiguration,         config_parse_prefix_flags,                                0,                             0
+IPv6Prefix.OnLink,                           config_parse_prefix_boolean,                              0,                             0
+IPv6Prefix.AddressAutoconfiguration,         config_parse_prefix_boolean,                              0,                             0
 IPv6Prefix.ValidLifetimeSec,                 config_parse_prefix_lifetime,                             0,                             0
 IPv6Prefix.PreferredLifetimeSec,             config_parse_prefix_lifetime,                             0,                             0
-IPv6Prefix.Assign,                           config_parse_prefix_assign,                               0,                             0
+IPv6Prefix.Assign,                           config_parse_prefix_boolean,                              0,                             0
 IPv6Prefix.RouteMetric,                      config_parse_prefix_metric,                               0,                             0
 IPv6Prefix.Token,                            config_parse_prefix_token,                                0,                             0
 IPv6RoutePrefix.Route,                       config_parse_route_prefix,                                0,                             0
@@ -528,11 +527,12 @@ DHCP.RouteMetric,                            config_parse_dhcp_or_ra_route_metri
 DHCP.RouteTable,                             config_parse_dhcp_or_ra_route_table,                      (RTPROT_DHCP<<16) | AF_UNSPEC, 0
 DHCP.UseTimezone,                            config_parse_bool,                                        0,                             offsetof(Network, dhcp_use_timezone)
 DHCP.ListenPort,                             config_parse_uint16,                                      0,                             offsetof(Network, dhcp_client_port)
-DHCP.RapidCommit,                            config_parse_bool,                                        0,                             offsetof(Network, dhcp6_rapid_commit)
+DHCP.RapidCommit,                            config_parse_warn_compat,                                 DISABLED_LEGACY,               0
 DHCP.ForceDHCPv6PDOtherInformation,          config_parse_bool,                                        0,                             offsetof(Network, dhcp6_force_pd_other_information)
 DHCPv4.UseDomainName,                        config_parse_dhcp_use_domains,                            AF_INET,                       0
 DHCPv4.CriticalConnection,                   config_parse_tristate,                                    0,                             offsetof(Network, dhcp_critical)
 DHCPv6.RouteMetric,                          config_parse_dhcp_or_ra_route_metric,                     AF_INET6,                      0
+DHCPv6.RapidCommit,                          config_parse_warn_compat,                                 DISABLED_LEGACY,               0
 IPv6AcceptRA.DenyList,                       config_parse_in_addr_prefixes,                            AF_INET6,                      offsetof(Network, ndisc_deny_listed_prefix)
 IPv6AcceptRA.BlackList,                      config_parse_in_addr_prefixes,                            AF_INET6,                      offsetof(Network, ndisc_deny_listed_prefix)
 TrafficControlQueueingDiscipline.Parent,                        config_parse_qdisc_parent,             _QDISC_KIND_INVALID,           0
index afbb9d61db4aaa7c2379c078d9d10d25545783c9..a367041e9916efd16f7104f20515a738abeac9eb 100644 (file)
@@ -403,7 +403,6 @@ int network_load_one(Manager *manager, OrderedHashmap **networks, const char *fi
                 .dhcp6_use_dns = true,
                 .dhcp6_use_hostname = true,
                 .dhcp6_use_ntp = true,
-                .dhcp6_rapid_commit = true,
                 .dhcp6_duid.type = _DUID_TYPE_INVALID,
 
                 .dhcp6_pd = -1,
@@ -420,6 +419,7 @@ int network_load_one(Manager *manager, OrderedHashmap **networks, const char *fi
                 .dhcp_server_emit_timezone = true,
 
                 .router_lifetime_usec = 30 * USEC_PER_MINUTE,
+                .router_dns_lifetime_usec = 7 * USEC_PER_DAY,
                 .router_emit_dns = true,
                 .router_emit_domains = true,
 
index ff9d1338fdad58a07a8a9c7e21d9ac49f3e0c7d6..bea882019a4cca9229120f8c3b0c79b8482a9eb2 100644 (file)
@@ -174,7 +174,6 @@ struct Network {
         bool dhcp6_use_hostname;
         bool dhcp6_use_ntp;
         bool dhcp6_use_ntp_set;
-        bool dhcp6_rapid_commit;
         bool dhcp6_route_table;
         bool dhcp6_route_table_set;
         bool dhcp6_route_table_set_explicitly;
index 34e6a41c34a536e2cace85557db3c9a6b2d27c3a..73e9bce52a02f1e4222ad4c18322289723fbbc84 100644 (file)
@@ -68,7 +68,6 @@ Prefix *prefix_free(Prefix *prefix) {
         }
 
         network_config_section_free(prefix->section);
-        sd_radv_prefix_unref(prefix->radv_prefix);
         set_free(prefix->tokens);
 
         return mfree(prefix);
@@ -76,21 +75,6 @@ Prefix *prefix_free(Prefix *prefix) {
 
 DEFINE_NETWORK_SECTION_FUNCTIONS(Prefix, prefix_free);
 
-static int prefix_new(Prefix **ret) {
-        _cleanup_(prefix_freep) Prefix *prefix = NULL;
-
-        prefix = new0(Prefix, 1);
-        if (!prefix)
-                return -ENOMEM;
-
-        if (sd_radv_prefix_new(&prefix->radv_prefix) < 0)
-                return -ENOMEM;
-
-        *ret = TAKE_PTR(prefix);
-
-        return 0;
-}
-
 static int prefix_new_static(Network *network, const char *filename, unsigned section_line, Prefix **ret) {
         _cleanup_(network_config_section_freep) NetworkConfigSection *n = NULL;
         _cleanup_(prefix_freep) Prefix *prefix = NULL;
@@ -111,19 +95,25 @@ static int prefix_new_static(Network *network, const char *filename, unsigned se
                 return 0;
         }
 
-        r = prefix_new(&prefix);
-        if (r < 0)
-                return r;
+        prefix = new(Prefix, 1);
+        if (!prefix)
+                return -ENOMEM;
 
-        prefix->network = network;
-        prefix->section = TAKE_PTR(n);
+        *prefix = (Prefix) {
+                .network = network,
+                .section = TAKE_PTR(n),
+
+                .preferred_lifetime = 7 * USEC_PER_DAY,
+                .valid_lifetime = 30 * USEC_PER_DAY,
+                .onlink = true,
+                .address_auto_configuration = true,
+        };
 
         r = hashmap_ensure_put(&network->prefixes_by_section, &network_config_hash_ops, prefix->section, prefix);
         if (r < 0)
                 return r;
 
         *ret = TAKE_PTR(prefix);
-
         return 0;
 }
 
@@ -137,28 +127,12 @@ RoutePrefix *route_prefix_free(RoutePrefix *prefix) {
         }
 
         network_config_section_free(prefix->section);
-        sd_radv_route_prefix_unref(prefix->radv_route_prefix);
 
         return mfree(prefix);
 }
 
 DEFINE_NETWORK_SECTION_FUNCTIONS(RoutePrefix, route_prefix_free);
 
-static int route_prefix_new(RoutePrefix **ret) {
-        _cleanup_(route_prefix_freep) RoutePrefix *prefix = NULL;
-
-        prefix = new0(RoutePrefix, 1);
-        if (!prefix)
-                return -ENOMEM;
-
-        if (sd_radv_route_prefix_new(&prefix->radv_route_prefix) < 0)
-                return -ENOMEM;
-
-        *ret = TAKE_PTR(prefix);
-
-        return 0;
-}
-
 static int route_prefix_new_static(Network *network, const char *filename, unsigned section_line, RoutePrefix **ret) {
         _cleanup_(network_config_section_freep) NetworkConfigSection *n = NULL;
         _cleanup_(route_prefix_freep) RoutePrefix *prefix = NULL;
@@ -179,19 +153,22 @@ static int route_prefix_new_static(Network *network, const char *filename, unsig
                 return 0;
         }
 
-        r = route_prefix_new(&prefix);
-        if (r < 0)
-                return r;
+        prefix = new(RoutePrefix, 1);
+        if (!prefix)
+                return -ENOMEM;
 
-        prefix->network = network;
-        prefix->section = TAKE_PTR(n);
+        *prefix = (RoutePrefix) {
+                .network = network,
+                .section = TAKE_PTR(n),
+
+                .lifetime = 7 * USEC_PER_DAY,
+        };
 
         r = hashmap_ensure_put(&network->route_prefixes_by_section, &network_config_hash_ops, prefix->section, prefix);
         if (r < 0)
                 return r;
 
         *ret = TAKE_PTR(prefix);
-
         return 0;
 }
 
@@ -206,28 +183,16 @@ int link_request_radv_addresses(Link *link) {
 
         HASHMAP_FOREACH(p, link->network->prefixes_by_section) {
                 _cleanup_set_free_ Set *addresses = NULL;
-                struct in6_addr prefix, *a;
-                uint8_t prefixlen;
+                struct in6_addr *a;
 
                 if (!p->assign)
                         continue;
 
-                r = sd_radv_prefix_get_prefix(p->radv_prefix, &prefix, &prefixlen);
-                if (r < 0)
-                        return r;
-
                 /* radv_generate_addresses() below requires the prefix length <= 64. */
-                if (prefixlen > 64) {
-                        _cleanup_free_ char *str = NULL;
-
-                        (void) in6_addr_prefix_to_string(&prefix, prefixlen, &str);
-                        log_link_debug(link,
-                                       "Prefix is longer than 64, refusing to assign an address in %s.",
-                                       strna(str));
+                if (p->prefixlen > 64)
                         continue;
-                }
 
-                r = radv_generate_addresses(link, p->tokens, &prefix, prefixlen, &addresses);
+                r = radv_generate_addresses(link, p->tokens, &p->prefix, p->prefixlen, &addresses);
                 if (r < 0)
                         return r;
 
@@ -241,7 +206,7 @@ int link_request_radv_addresses(Link *link) {
                         address->source = NETWORK_CONFIG_SOURCE_STATIC;
                         address->family = AF_INET6;
                         address->in_addr.in6 = *a;
-                        address->prefixlen = prefixlen;
+                        address->prefixlen = p->prefixlen;
                         address->route_metric = p->route_metric;
 
                         r = link_request_static_address(link, TAKE_PTR(address), true);
@@ -253,6 +218,77 @@ int link_request_radv_addresses(Link *link) {
         return 0;
 }
 
+static uint32_t usec_to_lifetime(usec_t usec) {
+        uint64_t t;
+
+        if (usec == USEC_INFINITY)
+                return UINT32_MAX;
+
+        t = DIV_ROUND_UP(usec, USEC_PER_SEC);
+        if (t >= UINT32_MAX)
+                return UINT32_MAX;
+
+        return (uint32_t) t;
+}
+
+static int radv_set_prefix(Link *link, Prefix *prefix) {
+        _cleanup_(sd_radv_prefix_unrefp) sd_radv_prefix *p = NULL;
+        int r;
+
+        assert(link);
+        assert(link->radv);
+        assert(prefix);
+
+        r = sd_radv_prefix_new(&p);
+        if (r < 0)
+                return r;
+
+        r = sd_radv_prefix_set_prefix(p, &prefix->prefix, prefix->prefixlen);
+        if (r < 0)
+                return r;
+
+        r = sd_radv_prefix_set_preferred_lifetime(p, usec_to_lifetime(prefix->preferred_lifetime));
+        if (r < 0)
+                return r;
+
+        r = sd_radv_prefix_set_valid_lifetime(p, usec_to_lifetime(prefix->valid_lifetime));
+        if (r < 0)
+                return r;
+
+        r = sd_radv_prefix_set_onlink(p, prefix->onlink);
+        if (r < 0)
+                return r;
+
+        r = sd_radv_prefix_set_address_autoconfiguration(p, prefix->address_auto_configuration);
+        if (r < 0)
+                return r;
+
+        return sd_radv_add_prefix(link->radv, p, false);
+}
+
+static int radv_set_route_prefix(Link *link, RoutePrefix *prefix) {
+        _cleanup_(sd_radv_route_prefix_unrefp) sd_radv_route_prefix *p = NULL;
+        int r;
+
+        assert(link);
+        assert(link->radv);
+        assert(prefix);
+
+        r = sd_radv_route_prefix_new(&p);
+        if (r < 0)
+                return r;
+
+        r = sd_radv_route_prefix_set_prefix(p, &prefix->prefix, prefix->prefixlen);
+        if (r < 0)
+                return r;
+
+        r = sd_radv_route_prefix_set_lifetime(p, usec_to_lifetime(prefix->lifetime));
+        if (r < 0)
+                return r;
+
+        return sd_radv_add_route_prefix(link->radv, p, false);
+}
+
 static int network_get_ipv6_dns(Network *network, struct in6_addr **ret_addresses, size_t *ret_size) {
         _cleanup_free_ struct in6_addr *addresses = NULL;
         size_t n_addresses = 0;
@@ -288,7 +324,6 @@ static int network_get_ipv6_dns(Network *network, struct in6_addr **ret_addresse
 
 static int radv_set_dns(Link *link, Link *uplink) {
         _cleanup_free_ struct in6_addr *dns = NULL;
-        usec_t lifetime_usec;
         size_t n_dns;
         int r;
 
@@ -311,13 +346,10 @@ static int radv_set_dns(Link *link, Link *uplink) {
                                 *(p++) = link->network->router_dns[i];
 
                 n_dns = p - dns;
-                lifetime_usec = link->network->router_dns_lifetime_usec;
 
                 goto set_dns;
         }
 
-        lifetime_usec = SD_RADV_DEFAULT_DNS_LIFETIME_USEC;
-
         r = network_get_ipv6_dns(link->network, &dns, &n_dns);
         if (r > 0)
                 goto set_dns;
@@ -334,26 +366,22 @@ static int radv_set_dns(Link *link, Link *uplink) {
 
 set_dns:
         return sd_radv_set_rdnss(link->radv,
-                                 DIV_ROUND_UP(lifetime_usec, USEC_PER_SEC),
+                                 usec_to_lifetime(link->network->router_dns_lifetime_usec),
                                  dns, n_dns);
 }
 
 static int radv_set_domains(Link *link, Link *uplink) {
-        OrderedSet *search_domains;
-        usec_t lifetime_usec;
         _cleanup_free_ char **s = NULL; /* just free() because the strings are owned by the set */
+        OrderedSet *search_domains;
 
         if (!link->network->router_emit_domains)
                 return 0;
 
         search_domains = link->network->router_search_domains;
-        lifetime_usec = link->network->router_dns_lifetime_usec;
 
         if (search_domains)
                 goto set_domains;
 
-        lifetime_usec = SD_RADV_DEFAULT_DNS_LIFETIME_USEC;
-
         search_domains = link->network->search_domains;
         if (search_domains)
                 goto set_domains;
@@ -374,7 +402,7 @@ set_domains:
                 return log_oom();
 
         return sd_radv_set_dnssl(link->radv,
-                                 DIV_ROUND_UP(lifetime_usec, USEC_PER_SEC),
+                                 usec_to_lifetime(link->network->router_dns_lifetime_usec),
                                  s);
 
 }
@@ -455,22 +483,14 @@ static int radv_configure(Link *link) {
         }
 
         HASHMAP_FOREACH(p, link->network->prefixes_by_section) {
-                r = sd_radv_add_prefix(link->radv, p->radv_prefix, false);
-                if (r == -EEXIST)
-                        continue;
-                if (r == -ENOEXEC) {
-                        log_link_warning_errno(link, r, "[IPv6Prefix] section configured without Prefix= setting, ignoring section.");
-                        continue;
-                }
-                if (r < 0)
+                r = radv_set_prefix(link, p);
+                if (r < 0 && r != -EEXIST)
                         return r;
         }
 
         HASHMAP_FOREACH(q, link->network->route_prefixes_by_section) {
-                r = sd_radv_add_route_prefix(link->radv, q->radv_route_prefix, false);
-                if (r == -EEXIST)
-                        continue;
-                if (r < 0)
+                r = radv_set_route_prefix(link, q);
+                if (r < 0 && r != -EEXIST)
                         return r;
         }
 
@@ -643,24 +663,94 @@ int radv_add_prefix(
         return 0;
 }
 
+static int prefix_section_verify(Prefix *p) {
+        assert(p);
+
+        if (section_is_invalid(p->section))
+                return -EINVAL;
+
+        if (in6_addr_is_null(&p->prefix))
+                return log_warning_errno(SYNTHETIC_ERRNO(EINVAL),
+                                         "%s: [IPv6Prefix] section without Prefix= field configured, "
+                                         "or specified prefix is the null address. "
+                                         "Ignoring [IPv6Prefix] section from line %u.",
+                                         p->section->filename, p->section->line);
+
+        if (p->prefixlen < 3 || p->prefixlen > 128)
+                return log_warning_errno(SYNTHETIC_ERRNO(EINVAL),
+                                         "%s: Invalid prefix length %u is specified in [IPv6Prefix] section. "
+                                         "Valid range is 3…128. Ignoring [IPv6Prefix] section from line %u.",
+                                         p->section->filename, p->prefixlen, p->section->line);
+
+        if (p->prefixlen > 64) {
+                _cleanup_free_ char *str = NULL;
+
+                if (p->assign)
+                        (void) in6_addr_prefix_to_string(&p->prefix, p->prefixlen, &str);
+
+                log_info("%s: Unusual prefix length %u (> 64) is specified in [IPv6Prefix] section from line %u%s%s.",
+                         p->section->filename, p->prefixlen, p->section->line,
+                         p->assign ? ", refusing to assign an address in " : "",
+                         p->assign ? strna(str) : "");
+
+                p->assign = false;
+        }
+
+        if (p->valid_lifetime == 0)
+                return log_warning_errno(SYNTHETIC_ERRNO(EINVAL),
+                                         "%s: The valid lifetime of prefix cannot be zero. "
+                                         "Ignoring [IPv6Prefix] section from line %u.",
+                                         p->section->filename, p->section->line);
+
+        if (p->preferred_lifetime > p->valid_lifetime)
+                return log_warning_errno(SYNTHETIC_ERRNO(EINVAL),
+                                         "%s: The preferred lifetime %s is longer than the valid lifetime %s. "
+                                         "Ignoring [IPv6Prefix] section from line %u.",
+                                         p->section->filename,
+                                         FORMAT_TIMESPAN(p->preferred_lifetime, USEC_PER_SEC),
+                                         FORMAT_TIMESPAN(p->valid_lifetime, USEC_PER_SEC),
+                                         p->section->line);
+
+        return 0;
+}
+
 void network_drop_invalid_prefixes(Network *network) {
-        Prefix *prefix;
+        Prefix *p;
 
         assert(network);
 
-        HASHMAP_FOREACH(prefix, network->prefixes_by_section)
-                if (section_is_invalid(prefix->section))
-                        prefix_free(prefix);
+        HASHMAP_FOREACH(p, network->prefixes_by_section)
+                if (prefix_section_verify(p) < 0)
+                        prefix_free(p);
+}
+
+static int route_prefix_section_verify(RoutePrefix *p) {
+        if (section_is_invalid(p->section))
+                return -EINVAL;
+
+        if (p->prefixlen > 128)
+                return log_warning_errno(SYNTHETIC_ERRNO(EINVAL),
+                                         "%s: Invalid prefix length %u is specified in [IPv6RoutePrefix] section. "
+                                         "Valid range is 0…128. Ignoring [IPv6RoutePrefix] section from line %u.",
+                                         p->section->filename, p->prefixlen, p->section->line);
+
+        if (p->lifetime == 0)
+                return log_warning_errno(SYNTHETIC_ERRNO(EINVAL),
+                                         "%s: The lifetime of route cannot be zero. "
+                                         "Ignoring [IPv6RoutePrefix] section from line %u.",
+                                         p->section->filename, p->section->line);
+
+        return 0;
 }
 
 void network_drop_invalid_route_prefixes(Network *network) {
-        RoutePrefix *prefix;
+        RoutePrefix *p;
 
         assert(network);
 
-        HASHMAP_FOREACH(prefix, network->route_prefixes_by_section)
-                if (section_is_invalid(prefix->section))
-                        route_prefix_free(prefix);
+        HASHMAP_FOREACH(p, network->route_prefixes_by_section)
+                if (route_prefix_section_verify(p) < 0)
+                        route_prefix_free(p);
 }
 
 int config_parse_prefix(
@@ -675,40 +765,36 @@ int config_parse_prefix(
                 void *data,
                 void *userdata) {
 
-        Network *network = userdata;
         _cleanup_(prefix_free_or_set_invalidp) Prefix *p = NULL;
-        uint8_t prefixlen = 64;
-        union in_addr_union in6addr;
+        Network *network = userdata;
+        union in_addr_union a;
         int r;
 
         assert(filename);
         assert(section);
         assert(lvalue);
         assert(rvalue);
-        assert(data);
+        assert(userdata);
 
         r = prefix_new_static(network, filename, section_line, &p);
         if (r < 0)
                 return log_oom();
 
-        r = in_addr_prefix_from_string(rvalue, AF_INET6, &in6addr, &prefixlen);
+        r = in_addr_prefix_from_string(rvalue, AF_INET6, &a, &p->prefixlen);
         if (r < 0) {
-                log_syntax(unit, LOG_WARNING, filename, line, r, "Prefix is invalid, ignoring assignment: %s", rvalue);
-                return 0;
-        }
-
-        r = sd_radv_prefix_set_prefix(p->radv_prefix, &in6addr.in6, prefixlen);
-        if (r < 0) {
-                log_syntax(unit, LOG_WARNING, filename, line, r, "Failed to set radv prefix, ignoring assignment: %s", rvalue);
+                log_syntax(unit, LOG_WARNING, filename, line, r,
+                           "Prefix is invalid, ignoring assignment: %s", rvalue);
                 return 0;
         }
 
-        p = NULL;
+        (void) in6_addr_mask(&a.in6, p->prefixlen);
+        p->prefix = a.in6;
 
+        TAKE_PTR(p);
         return 0;
 }
 
-int config_parse_prefix_flags(
+int config_parse_prefix_boolean(
                 const char *unit,
                 const char *filename,
                 unsigned line,
@@ -720,15 +806,15 @@ int config_parse_prefix_flags(
                 void *data,
                 void *userdata) {
 
-        Network *network = userdata;
         _cleanup_(prefix_free_or_set_invalidp) Prefix *p = NULL;
+        Network *network = userdata;
         int r;
 
         assert(filename);
         assert(section);
         assert(lvalue);
         assert(rvalue);
-        assert(data);
+        assert(userdata);
 
         r = prefix_new_static(network, filename, section_line, &p);
         if (r < 0)
@@ -736,21 +822,21 @@ int config_parse_prefix_flags(
 
         r = parse_boolean(rvalue);
         if (r < 0) {
-                log_syntax(unit, LOG_WARNING, filename, line, r, "Failed to parse %s=, ignoring assignment: %s", lvalue, rvalue);
+                log_syntax(unit, LOG_WARNING, filename, line, r,
+                           "Failed to parse %s=, ignoring assignment: %s", lvalue, rvalue);
                 return 0;
         }
 
         if (streq(lvalue, "OnLink"))
-                r = sd_radv_prefix_set_onlink(p->radv_prefix, r);
+                p->onlink = r;
         else if (streq(lvalue, "AddressAutoconfiguration"))
-                r = sd_radv_prefix_set_address_autoconfiguration(p->radv_prefix, r);
-        if (r < 0) {
-                log_syntax(unit, LOG_WARNING, filename, line, r, "Failed to set %s=, ignoring assignment: %m", lvalue);
-                return 0;
-        }
-
-        p = NULL;
+                p->address_auto_configuration = r;
+        else if (streq(lvalue, "Assign"))
+                p->assign = r;
+        else
+                assert_not_reached();
 
+        TAKE_PTR(p);
         return 0;
 }
 
@@ -766,8 +852,8 @@ int config_parse_prefix_lifetime(
                 void *data,
                 void *userdata) {
 
-        Network *network = userdata;
         _cleanup_(prefix_free_or_set_invalidp) Prefix *p = NULL;
+        Network *network = userdata;
         usec_t usec;
         int r;
 
@@ -775,7 +861,7 @@ int config_parse_prefix_lifetime(
         assert(section);
         assert(lvalue);
         assert(rvalue);
-        assert(data);
+        assert(userdata);
 
         r = prefix_new_static(network, filename, section_line, &p);
         if (r < 0)
@@ -783,64 +869,25 @@ int config_parse_prefix_lifetime(
 
         r = parse_sec(rvalue, &usec);
         if (r < 0) {
-                log_syntax(unit, LOG_WARNING, filename, line, r, "Lifetime is invalid, ignoring assignment: %s", rvalue);
-                return 0;
-        }
-
-        /* a value of 0xffffffff represents infinity */
-        if (streq(lvalue, "PreferredLifetimeSec"))
-                r = sd_radv_prefix_set_preferred_lifetime(p->radv_prefix,
-                                                          DIV_ROUND_UP(usec, USEC_PER_SEC));
-        else if (streq(lvalue, "ValidLifetimeSec"))
-                r = sd_radv_prefix_set_valid_lifetime(p->radv_prefix,
-                                                      DIV_ROUND_UP(usec, USEC_PER_SEC));
-        if (r < 0) {
-                log_syntax(unit, LOG_WARNING, filename, line, r, "Failed to set %s=, ignoring assignment: %m", lvalue);
+                log_syntax(unit, LOG_WARNING, filename, line, r,
+                           "Lifetime is invalid, ignoring assignment: %s", rvalue);
                 return 0;
         }
 
-        p = NULL;
-
-        return 0;
-}
-
-int config_parse_prefix_assign(
-                const char *unit,
-                const char *filename,
-                unsigned line,
-                const char *section,
-                unsigned section_line,
-                const char *lvalue,
-                int ltype,
-                const char *rvalue,
-                void *data,
-                void *userdata) {
-
-        Network *network = userdata;
-        _cleanup_(prefix_free_or_set_invalidp) Prefix *p = NULL;
-        int r;
-
-        assert(filename);
-        assert(section);
-        assert(lvalue);
-        assert(rvalue);
-        assert(data);
-
-        r = prefix_new_static(network, filename, section_line, &p);
-        if (r < 0)
-                return log_oom();
-
-        r = parse_boolean(rvalue);
-        if (r < 0) {
-                log_syntax(unit, LOG_WARNING, filename, line, r,
-                           "Failed to parse %s=, ignoring assignment: %s",
-                           lvalue, rvalue);
+        if (usec != USEC_INFINITY && DIV_ROUND_UP(usec, USEC_PER_SEC) >= UINT32_MAX) {
+                log_syntax(unit, LOG_WARNING, filename, line, 0,
+                           "Lifetime is too long, ignoring assignment: %s", rvalue);
                 return 0;
         }
 
-        p->assign = r;
-        p = NULL;
+        if (streq(lvalue, "PreferredLifetimeSec"))
+                p->preferred_lifetime = usec;
+        else if (streq(lvalue, "ValidLifetimeSec"))
+                p->valid_lifetime = usec;
+        else
+                assert_not_reached();
 
+        TAKE_PTR(p);
         return 0;
 }
 
@@ -856,15 +903,15 @@ int config_parse_prefix_metric(
                 void *data,
                 void *userdata) {
 
-        Network *network = userdata;
         _cleanup_(prefix_free_or_set_invalidp) Prefix *p = NULL;
+        Network *network = userdata;
         int r;
 
         assert(filename);
         assert(section);
         assert(lvalue);
         assert(rvalue);
-        assert(data);
+        assert(userdata);
 
         r = prefix_new_static(network, filename, section_line, &p);
         if (r < 0)
@@ -879,7 +926,6 @@ int config_parse_prefix_metric(
         }
 
         TAKE_PTR(p);
-
         return 0;
 }
 
@@ -930,36 +976,32 @@ int config_parse_route_prefix(
                 void *data,
                 void *userdata) {
 
-        Network *network = userdata;
         _cleanup_(route_prefix_free_or_set_invalidp) RoutePrefix *p = NULL;
-        uint8_t prefixlen = 64;
-        union in_addr_union in6addr;
+        Network *network = userdata;
+        union in_addr_union a;
         int r;
 
         assert(filename);
         assert(section);
         assert(lvalue);
         assert(rvalue);
-        assert(data);
+        assert(userdata);
 
         r = route_prefix_new_static(network, filename, section_line, &p);
         if (r < 0)
                 return log_oom();
 
-        r = in_addr_prefix_from_string(rvalue, AF_INET6, &in6addr, &prefixlen);
-        if (r < 0) {
-                log_syntax(unit, LOG_WARNING, filename, line, r, "Route prefix is invalid, ignoring assignment: %s", rvalue);
-                return 0;
-        }
-
-        r = sd_radv_prefix_set_route_prefix(p->radv_route_prefix, &in6addr.in6, prefixlen);
+        r = in_addr_prefix_from_string(rvalue, AF_INET6, &a, &p->prefixlen);
         if (r < 0) {
-                log_syntax(unit, LOG_WARNING, filename, line, r, "Failed to set route prefix, ignoring assignment: %m");
+                log_syntax(unit, LOG_WARNING, filename, line, r,
+                           "Route prefix is invalid, ignoring assignment: %s", rvalue);
                 return 0;
         }
 
-        p = NULL;
+        (void) in6_addr_mask(&a.in6, p->prefixlen);
+        p->prefix = a.in6;
 
+        TAKE_PTR(p);
         return 0;
 }
 
@@ -975,8 +1017,8 @@ int config_parse_route_prefix_lifetime(
                 void *data,
                 void *userdata) {
 
-        Network *network = userdata;
         _cleanup_(route_prefix_free_or_set_invalidp) RoutePrefix *p = NULL;
+        Network *network = userdata;
         usec_t usec;
         int r;
 
@@ -984,7 +1026,7 @@ int config_parse_route_prefix_lifetime(
         assert(section);
         assert(lvalue);
         assert(rvalue);
-        assert(data);
+        assert(userdata);
 
         r = route_prefix_new_static(network, filename, section_line, &p);
         if (r < 0)
@@ -997,16 +1039,15 @@ int config_parse_route_prefix_lifetime(
                 return 0;
         }
 
-        /* a value of 0xffffffff represents infinity */
-        r = sd_radv_route_prefix_set_lifetime(p->radv_route_prefix, DIV_ROUND_UP(usec, USEC_PER_SEC));
-        if (r < 0) {
-                log_syntax(unit, LOG_WARNING, filename, line, r,
-                           "Failed to set route lifetime, ignoring assignment: %m");
+        if (usec != USEC_INFINITY && DIV_ROUND_UP(usec, USEC_PER_SEC) >= UINT32_MAX) {
+                log_syntax(unit, LOG_WARNING, filename, line, 0,
+                           "Lifetime is too long, ignoring assignment: %s", rvalue);
                 return 0;
         }
 
-        p = NULL;
+        p->lifetime = usec;
 
+        TAKE_PTR(p);
         return 0;
 }
 
index 5c869d8623e61c7bc8df47f940318bf873b03720..d51fe323dcec8216eed1efee25bad58f64749aee 100644 (file)
@@ -31,7 +31,13 @@ typedef struct Prefix {
         Network *network;
         NetworkConfigSection *section;
 
-        sd_radv_prefix *radv_prefix;
+        struct in6_addr prefix;
+        uint8_t prefixlen;
+        usec_t preferred_lifetime;
+        usec_t valid_lifetime;
+
+        bool onlink;
+        bool address_auto_configuration;
 
         bool assign;
         uint32_t route_metric;
@@ -42,7 +48,9 @@ typedef struct RoutePrefix {
         Network *network;
         NetworkConfigSection *section;
 
-        sd_radv_route_prefix *radv_route_prefix;
+        struct in6_addr prefix;
+        uint8_t prefixlen;
+        usec_t lifetime;
 } RoutePrefix;
 
 Prefix *prefix_free(Prefix *prefix);
@@ -67,9 +75,8 @@ RADVPrefixDelegation radv_prefix_delegation_from_string(const char *s) _pure_;
 CONFIG_PARSER_PROTOTYPE(config_parse_router_prefix_delegation);
 CONFIG_PARSER_PROTOTYPE(config_parse_router_preference);
 CONFIG_PARSER_PROTOTYPE(config_parse_prefix);
-CONFIG_PARSER_PROTOTYPE(config_parse_prefix_flags);
+CONFIG_PARSER_PROTOTYPE(config_parse_prefix_boolean);
 CONFIG_PARSER_PROTOTYPE(config_parse_prefix_lifetime);
-CONFIG_PARSER_PROTOTYPE(config_parse_prefix_assign);
 CONFIG_PARSER_PROTOTYPE(config_parse_prefix_metric);
 CONFIG_PARSER_PROTOTYPE(config_parse_prefix_token);
 CONFIG_PARSER_PROTOTYPE(config_parse_radv_dns);
index c1c26d21c5a92ad5a1ca097d80c1e44ebc250acb..e3e260754d66752cd4ccaaa2d38bde4229c9f96d 100644 (file)
@@ -24,7 +24,7 @@ int main(int argc, char **argv) {
         test_table(bond_primary_reselect, NETDEV_BOND_PRIMARY_RESELECT);
         test_table(bond_xmit_hash_policy, NETDEV_BOND_XMIT_HASH_POLICY);
         test_table(dhcp6_message_status, DHCP6_STATUS);
-        test_table_sparse(dhcp6_message_type, DHCP6_MESSAGE); /* enum starts from 1 */
+        test_table_sparse(dhcp6_message_type, DHCP6_MESSAGE_TYPE); /* enum starts from 1 */
         test_table(dhcp_use_domains, DHCP_USE_DOMAINS);
         test_table(duplex, DUP);
         test_table(ip6tnl_mode, NETDEV_IP6_TNL_MODE);
index 9d5051d46d92252a86382bc147769e021cb08abd..2890190eec917577e99f6df463594bddedbdc645 100644 (file)
@@ -174,7 +174,7 @@ int expose_port_send_rtnl(int send_fd) {
 
         assert(send_fd >= 0);
 
-        fd = socket(PF_NETLINK, SOCK_RAW|SOCK_CLOEXEC|SOCK_NONBLOCK, NETLINK_ROUTE);
+        fd = socket(AF_NETLINK, SOCK_RAW|SOCK_CLOEXEC|SOCK_NONBLOCK, NETLINK_ROUTE);
         if (fd < 0)
                 return log_error_errno(errno, "Failed to allocate container netlink: %m");
 
index 3847fe4ec4976b1f1b7059c3458ae74745e92772..edc0f663bba09a4a9233a44362ef040c1b424678 100644 (file)
@@ -609,7 +609,7 @@ int config_parse_private_users(
 
                 range = strchr(rvalue, ':');
                 if (range) {
-                        shift = strndupa(rvalue, range - rvalue);
+                        shift = strndupa_safe(rvalue, range - rvalue);
                         range++;
 
                         r = safe_atou32(range, &rn);
index 29f2c54ab13aa046961073ffeb33a9345b52c6c7..265e77c0a2468f9bbe1095946beaff4cc537fe4d 100644 (file)
@@ -52,7 +52,7 @@ static void test_oomd_cgroup_kill(void) {
         /* Create another cgroup below this one for the pids we forked off. We need this to be managed
          * by the test so that pid1 doesn't delete it before we can read the xattrs. */
         cgroup = path_join(cgroup_root, "oomdkilltest");
-        assert(cgroup);
+        assert_se(cgroup);
         assert_se(cg_create(SYSTEMD_CGROUP_CONTROLLER, cgroup) >= 0);
 
         /* If we don't have permissions to set xattrs we're likely in a userns or missing capabilities */
index 48d99c0ca2be0872e2fa3b2ebc45aac906ed4b93..8ccb8f5228ed4eb829c2017e69dc9a55eafb3a1f 100644 (file)
@@ -718,7 +718,7 @@ static int unit_file_is_active(
                 at = strchr(name, '@');
                 assert(at);
 
-                prefix = strndupa(name, at + 1 - name);
+                prefix = strndupa_safe(name, at + 1 - name);
                 joined = strjoina(prefix, "*", at + 1);
 
                 r = sd_bus_message_append_strv(m, STRV_MAKE(joined));
index 5a175b11373bb1206d7de456c89ca37d66c2a6a0..99876dbdf66c811c26fc33bddbe69fbcfcb3135b 100644 (file)
@@ -623,7 +623,7 @@ static int resolve_rfc4501(sd_bus *bus, const char *name) {
 
         q = strchr(p, '?');
         if (q) {
-                n = strndupa(p, q - p);
+                n = strndupa_safe(p, q - p);
                 q++;
 
                 for (;;) {
@@ -1001,7 +1001,7 @@ static int resolve_tlsa(sd_bus *bus, const char *family, const char *address) {
                 if (r < 0)
                         return log_error_errno(r, "Invalid port \"%s\".", port + 1);
 
-                address = strndupa(address, port - address);
+                address = strndupa_safe(address, port - address);
         }
 
         r = asprintf(&full, "_%u._%s.%s",
index 6706885ebd0e63b1f74521c0c8d8b1566157746f..cc55a980ad2e605f41956c2da511ade784eefb06 100644 (file)
@@ -105,14 +105,14 @@ static void test_parse_etc_hosts(void) {
         assert_se(address_equal_4(bn->addresses[2], inet_addr("1.2.3.11")));
         assert_se(address_equal_4(bn->addresses[3], inet_addr("1.2.3.12")));
 
-        assert(!hashmap_get(hosts.by_name, "within.comment"));
-        assert(!hashmap_get(hosts.by_name, "within.comment2"));
-        assert(!hashmap_get(hosts.by_name, "within.comment3"));
-        assert(!hashmap_get(hosts.by_name, "#"));
-
-        assert(!hashmap_get(hosts.by_name, "short.address"));
-        assert(!hashmap_get(hosts.by_name, "long.address"));
-        assert(!hashmap_get(hosts.by_name, "multi.colon"));
+        assert_se(!hashmap_get(hosts.by_name, "within.comment"));
+        assert_se(!hashmap_get(hosts.by_name, "within.comment2"));
+        assert_se(!hashmap_get(hosts.by_name, "within.comment3"));
+        assert_se(!hashmap_get(hosts.by_name, "#"));
+
+        assert_se(!hashmap_get(hosts.by_name, "short.address"));
+        assert_se(!hashmap_get(hosts.by_name, "long.address"));
+        assert_se(!hashmap_get(hosts.by_name, "multi.colon"));
         assert_se(!set_contains(hosts.no_address, "short.address"));
         assert_se(!set_contains(hosts.no_address, "long.address"));
         assert_se(!set_contains(hosts.no_address, "multi.colon"));
index 4575bb4e2ff21ca33087eb0cfdc5a1b08163c559..a73e1e995b0cc7df29f2bb2c993b5a0a0a55962d 100644 (file)
@@ -38,7 +38,27 @@ static const char *const bpf_cgroup_attach_type_table[__MAX_BPF_ATTACH_TYPE] = {
 
 DEFINE_STRING_TABLE_LOOKUP(bpf_cgroup_attach_type, int);
 
-DEFINE_HASH_OPS_WITH_KEY_DESTRUCTOR(bpf_program_hash_ops, void, trivial_hash_func, trivial_compare_func, bpf_program_unref);
+DEFINE_HASH_OPS_WITH_KEY_DESTRUCTOR(bpf_program_hash_ops, void, trivial_hash_func, trivial_compare_func, bpf_program_free);
+
+BPFProgram *bpf_program_free(BPFProgram *p) {
+        if (!p)
+                return NULL;
+        /* Unfortunately, the kernel currently doesn't implicitly detach BPF programs from their cgroups when the last
+         * fd to the BPF program is closed. This has nasty side-effects since this means that abnormally terminated
+         * programs that attached one of their BPF programs to a cgroup will leave this program pinned for good with
+         * zero chance of recovery, until the cgroup is removed. This is particularly problematic if the cgroup in
+         * question is the root cgroup (or any other cgroup belonging to a service that cannot be restarted during
+         * operation, such as dbus), as the memory for the BPF program can only be reclaimed through a reboot. To
+         * counter this, we track closely to which cgroup a program was attached to and will detach it on our own
+         * whenever we close the BPF fd. */
+        (void) bpf_program_cgroup_detach(p);
+
+        safe_close(p->kernel_fd);
+        free(p->instructions);
+        free(p->attached_path);
+
+        return mfree(p);
+}
 
  /* struct bpf_prog_info info must be initialized since its value is both input and output
   * for BPF_OBJ_GET_INFO_BY_FD syscall. */
@@ -61,14 +81,13 @@ static int bpf_program_get_info_by_fd(int prog_fd, struct bpf_prog_info *info, u
 }
 
 int bpf_program_new(uint32_t prog_type, BPFProgram **ret) {
-        _cleanup_(bpf_program_unrefp) BPFProgram *p = NULL;
+        _cleanup_(bpf_program_freep) BPFProgram *p = NULL;
 
         p = new(BPFProgram, 1);
         if (!p)
                 return -ENOMEM;
 
         *p = (BPFProgram) {
-                .n_ref = 1,
                 .prog_type = prog_type,
                 .kernel_fd = -1,
         };
@@ -79,7 +98,7 @@ int bpf_program_new(uint32_t prog_type, BPFProgram **ret) {
 }
 
 int bpf_program_new_from_bpffs_path(const char *path, BPFProgram **ret) {
-        _cleanup_(bpf_program_unrefp) BPFProgram *p = NULL;
+        _cleanup_(bpf_program_freep) BPFProgram *p = NULL;
         struct bpf_prog_info info = {};
         int r;
 
@@ -92,7 +111,6 @@ int bpf_program_new_from_bpffs_path(const char *path, BPFProgram **ret) {
 
         *p = (BPFProgram) {
                 .prog_type = BPF_PROG_TYPE_UNSPEC,
-                .n_ref = 1,
                 .kernel_fd = -1,
         };
 
@@ -110,27 +128,6 @@ int bpf_program_new_from_bpffs_path(const char *path, BPFProgram **ret) {
         return 0;
 }
 
-static BPFProgram *bpf_program_free(BPFProgram *p) {
-        assert(p);
-
-        /* Unfortunately, the kernel currently doesn't implicitly detach BPF programs from their cgroups when the last
-         * fd to the BPF program is closed. This has nasty side-effects since this means that abnormally terminated
-         * programs that attached one of their BPF programs to a cgroup will leave this programs pinned for good with
-         * zero chance of recovery, until the cgroup is removed. This is particularly problematic if the cgroup in
-         * question is the root cgroup (or any other cgroup belonging to a service that cannot be restarted during
-         * operation, such as dbus), as the memory for the BPF program can only be reclaimed through a reboot. To
-         * counter this, we track closely to which cgroup a program was attached to and will detach it on our own
-         * whenever we close the BPF fd. */
-        (void) bpf_program_cgroup_detach(p);
-
-        safe_close(p->kernel_fd);
-        free(p->instructions);
-        free(p->attached_path);
-
-        return mfree(p);
-}
-
-DEFINE_TRIVIAL_REF_UNREF_FUNC(BPFProgram, bpf_program, bpf_program_free);
 
 int bpf_program_add_instructions(BPFProgram *p, const struct bpf_insn *instructions, size_t count) {
 
@@ -424,7 +421,7 @@ int bpf_program_serialize_attachment_set(FILE *f, FDSet *fds, const char *key, S
 
 int bpf_program_deserialize_attachment(const char *v, FDSet *fds, BPFProgram **bpfp) {
         _cleanup_free_ char *sfd = NULL, *sat = NULL, *unescaped = NULL;
-        _cleanup_(bpf_program_unrefp) BPFProgram *p = NULL;
+        _cleanup_(bpf_program_freep) BPFProgram *p = NULL;
         _cleanup_close_ int fd = -1;
         ssize_t l;
         int ifd, at, r;
@@ -470,7 +467,6 @@ int bpf_program_deserialize_attachment(const char *v, FDSet *fds, BPFProgram **b
                 return -ENOMEM;
 
         *p = (BPFProgram) {
-                .n_ref = 1,
                 .kernel_fd = TAKE_FD(fd),
                 .prog_type = BPF_PROG_TYPE_UNSPEC,
                 .attached_path = TAKE_PTR(unescaped),
@@ -478,7 +474,7 @@ int bpf_program_deserialize_attachment(const char *v, FDSet *fds, BPFProgram **b
         };
 
         if (*bpfp)
-                bpf_program_unref(*bpfp);
+                bpf_program_free(*bpfp);
 
         *bpfp = TAKE_PTR(p);
         return 0;
index 908af1a1b2a12001738c885d65f687df3cfcc3c1..e54900fa2fe8bf3228254cf4479b42e2c4f8a937 100644 (file)
@@ -17,8 +17,6 @@ typedef struct BPFProgram BPFProgram;
  * we attach it, but it might happen that we operate with programs that aren't loaded or aren't attached, or
  * where we don't have the code. */
 struct BPFProgram {
-        unsigned n_ref;
-
         /* The loaded BPF program, if loaded */
         int kernel_fd;
         uint32_t prog_type;
@@ -36,8 +34,7 @@ struct BPFProgram {
 
 int bpf_program_new(uint32_t prog_type, BPFProgram **ret);
 int bpf_program_new_from_bpffs_path(const char *path, BPFProgram **ret);
-BPFProgram *bpf_program_ref(BPFProgram *p);
-BPFProgram *bpf_program_unref(BPFProgram *p);
+BPFProgram *bpf_program_free(BPFProgram *p);
 
 int bpf_program_add_instructions(BPFProgram *p, const struct bpf_insn *insn, size_t count);
 int bpf_program_load_kernel(BPFProgram *p, char *log_buf, size_t log_size);
@@ -63,4 +60,4 @@ int bpf_map_lookup_element(int fd, const void *key, void *value);
 int bpf_cgroup_attach_type_from_string(const char *str) _pure_;
 const char *bpf_cgroup_attach_type_to_string(int attach_type) _const_;
 
-DEFINE_TRIVIAL_CLEANUP_FUNC(BPFProgram*, bpf_program_unref);
+DEFINE_TRIVIAL_CLEANUP_FUNC(BPFProgram*, bpf_program_free);
index feb6d3807f77c88ef86ee8f1964fa162b1c349ea..8b4f66b22e91ccdcf7b1899f774754fa98158ed1 100644 (file)
@@ -130,7 +130,7 @@ int bus_property_get_rlimit(
                 int z;
 
                 /* Chop off "Soft" suffix */
-                s = is_soft ? strndupa(property, is_soft - property) : property;
+                s = is_soft ? strndupa_safe(property, is_soft - property) : property;
 
                 /* Skip over any prefix, such as "Default" */
                 assert_se(p = strstr(s, "Limit"));
index 3bdcba325ffecf37581d0b91b98aa3c4b404be02..50deb9252e26309c97e54730a6031b3f7eb8afa2 100644 (file)
@@ -46,7 +46,7 @@ static int add_cgroup(Hashmap *cgroups, const char *path, bool is_const, struct
                 if (!e)
                         return -EINVAL;
 
-                pp = strndupa(path, e - path);
+                pp = strndupa_safe(path, e - path);
 
                 r = add_cgroup(cgroups, pp, false, &parent);
                 if (r < 0)
index 8b81e8058b32f7063b036ed6cc0c0330af2641e6..7df1e0b3108b0be36d9ea306bdeb2bb5dd2dcc7f 100644 (file)
@@ -605,7 +605,7 @@ static int bus_append_cgroup_property(sd_bus_message *m, const char *field, cons
 
                         e = strchr(eq, ' ');
                         if (e) {
-                                path = strndupa(eq, e - eq);
+                                path = strndupa_safe(eq, e - eq);
                                 rwm = e+1;
                         }
 
@@ -631,7 +631,7 @@ static int bus_append_cgroup_property(sd_bus_message *m, const char *field, cons
                                                        "Failed to parse %s value %s.",
                                                        field, eq);
 
-                        path = strndupa(eq, e - eq);
+                        path = strndupa_safe(eq, e - eq);
                         bandwidth = e+1;
 
                         if (streq(bandwidth, "infinity"))
@@ -665,7 +665,7 @@ static int bus_append_cgroup_property(sd_bus_message *m, const char *field, cons
                                                        "Failed to parse %s value %s.",
                                                        field, eq);
 
-                        path = strndupa(eq, e - eq);
+                        path = strndupa_safe(eq, e - eq);
                         weight = e+1;
 
                         r = safe_atou64(weight, &u);
@@ -696,7 +696,7 @@ static int bus_append_cgroup_property(sd_bus_message *m, const char *field, cons
                                                        "Failed to parse %s value %s.",
                                                        field, eq);
 
-                        path = strndupa(eq, e - eq);
+                        path = strndupa_safe(eq, e - eq);
                         target = e+1;
 
                         r = parse_sec(target, &usec);
@@ -2402,7 +2402,7 @@ int bus_append_unit_property_assignment(sd_bus_message *m, UnitType t, const cha
                 return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
                                        "Not an assignment: %s", assignment);
 
-        field = strndupa(assignment, eq - assignment);
+        field = strndupa_safe(assignment, eq - assignment);
         eq++;
 
         switch (t) {
index 7dee7e9512776339b00812be47b19df8cded7ff8..2221fd07c2894a511b0518d9352cfebe317664a3 100644 (file)
 #include "stdio-util.h"
 #include "string-util.h"
 #include "user-util.h"
+#include "virt.h"
+
+static int cg_any_controller_used_for_v1(void) {
+        _cleanup_free_ char *buf = NULL;
+        _cleanup_strv_free_ char **lines = NULL;
+        char **line;
+        int r;
+
+        r = read_full_virtual_file("/proc/cgroups", &buf, NULL);
+        if (r < 0)
+                return log_debug_errno(r, "Could not read /proc/cgroups, ignoring: %m");
+
+        r = strv_split_newlines_full(&lines, buf, 0);
+        if (r < 0)
+                return r;
+
+        /* The intention of this is to check if the fully unified cgroup tree setup is possible, meaning all
+         * enabled kernel cgroup controllers are currently not in use by cgroup1.  For reference:
+         * https://systemd.io/CGROUP_DELEGATION/#three-different-tree-setups-
+         *
+         * Note that this is typically only useful to check inside a container where we don't know what
+         * cgroup tree setup is in use by the host; if the host is using legacy or hybrid, we can't use
+         * unified since some or all controllers would be missing. This is not the best way to detect this,
+         * as whatever container manager created our container should have mounted /sys/fs/cgroup
+         * appropriately, but in case that wasn't done, we try to detect if it's possible for us to use
+         * unified cgroups. */
+        STRV_FOREACH(line, lines) {
+                _cleanup_free_ char *name = NULL, *hierarchy_id = NULL, *num = NULL, *enabled = NULL;
+
+                /* Skip header line */
+                if (startswith(*line, "#"))
+                        continue;
+
+                const char *p = *line;
+                r = extract_many_words(&p, NULL, 0, &name, &hierarchy_id, &num, &enabled, NULL);
+                if (r < 0)
+                        return log_debug_errno(r, "Error parsing /proc/cgroups line, ignoring: %m");
+                else if (r < 4) {
+                        log_debug("Invalid /proc/cgroups line, ignoring.");
+                        continue;
+                }
+
+                /* Ignore disabled controllers. */
+                if (streq(enabled, "0"))
+                        continue;
+
+                /* Ignore controllers we don't care about. */
+                if (cgroup_controller_from_string(name) < 0)
+                        continue;
+
+                /* Since the unified cgroup doesn't use multiple hierarchies, if any controller has a
+                 * non-zero hierarchy_id that means it's in use already in a legacy (or hybrid) cgroup v1
+                 * hierarchy, and can't be used in a unified cgroup. */
+                if (!streq(hierarchy_id, "0")) {
+                        log_debug("Cgroup controller %s in use by legacy v1 hierarchy.", name);
+                        return 1;
+                }
+        }
+
+        return 0;
+}
 
 bool cg_is_unified_wanted(void) {
         static thread_local int wanted = -1;
@@ -45,6 +106,10 @@ bool cg_is_unified_wanted(void) {
         if (r > 0 && streq_ptr(c, "all"))
                 return (wanted = true);
 
+        /* If any controller is in use as v1, don't use unified. */
+        if (cg_any_controller_used_for_v1() > 0)
+                return (wanted = false);
+
         return (wanted = is_default);
 }
 
index 74cebe1f7116bbbcd413913a0aba860df0b8916c..6b2289defa129e7c7ea947fd68d7fbf9b88e6347 100644 (file)
@@ -546,7 +546,7 @@ static int device_wait_for_initialization_harder(
 
                 (void) sd_device_get_sysname(device, &sn);
                 log_device_debug(device,
-                                 "Waiting for device '%s' to initialize for %s.", strna(sn), FORMAT_TIMESPAN(left, 0));
+                                 "Will wait up to %s for '%s' to initialize…", FORMAT_TIMESPAN(left, 0), strna(sn));
         }
 
         if (left != USEC_INFINITY)
index 787bb8fec944b013fcfaf4339c20432d486aa011..f54b187a1b9f2c842f39dc5ea2ae67eb93bcd7a9 100644 (file)
@@ -680,7 +680,7 @@ int dns_name_change_suffix(const char *name, const char *old_suffix, const char
         }
 
         /* Found it! Now generate the new name */
-        prefix = strndupa(name, saved_before - name);
+        prefix = strndupa_safe(name, saved_before - name);
 
         r = dns_name_concat(prefix, new_suffix, 0, ret);
         if (r < 0)
@@ -1028,7 +1028,7 @@ static bool dns_service_name_label_is_valid(const char *label, size_t n) {
         if (memchr(label, 0, n))
                 return false;
 
-        s = strndupa(label, n);
+        s = strndupa_safe(label, n);
         return dns_service_name_is_valid(s);
 }
 
index ee7be4635fa77e312d48f929883045c53b64a7a2..333e5a487977c2792571238f04c6be10def51fac 100644 (file)
@@ -756,7 +756,7 @@ int ethtool_set_features(int *ethtool_fd, const char *ifname, const int features
 static int get_glinksettings(int fd, struct ifreq *ifr, struct ethtool_link_usettings **ret) {
         struct ecmd {
                 struct ethtool_link_settings req;
-                __u32 link_mode_data[3 * ETHTOOL_LINK_MODE_MASK_MAX_KERNEL_NU32];
+                uint32_t link_mode_data[3 * ETHTOOL_LINK_MODE_MASK_MAX_KERNEL_NU32];
         } ecmd = {
                 .req.cmd = ETHTOOL_GLINKSETTINGS,
         };
@@ -857,7 +857,7 @@ static int get_gset(int fd, struct ifreq *ifr, struct ethtool_link_usettings **r
 static int set_slinksettings(int fd, struct ifreq *ifr, const struct ethtool_link_usettings *u) {
         struct {
                 struct ethtool_link_settings req;
-                __u32 link_mode_data[3 * ETHTOOL_LINK_MODE_MASK_MAX_KERNEL_NU32];
+                uint32_t link_mode_data[3 * ETHTOOL_LINK_MODE_MASK_MAX_KERNEL_NU32];
         } ecmd = {};
         unsigned offset;
 
index d53a394895aae835f1334fe137ed2e67619aace9..55bb427e7bfb13e7f4abdbf6c1bcaf1a9d0af13f 100644 (file)
@@ -128,7 +128,7 @@ int fw_iptables_add_masquerade(
         mr->rangesize = 1;
 
         /* Create a search mask entry */
-        mask = alloca(sz);
+        mask = alloca_safe(sz);
         memset(mask, 0xFF, sz);
 
         if (add) {
index bbb152481ec42f9eca0a63d38d13d82f734d94e4..c6caf9330a5c812f575726c544e5e74363205552 100644 (file)
@@ -316,7 +316,7 @@ int journal_importer_process_data(JournalImporter *imp) {
                         if (!journal_field_valid(line, sep - line, true)) {
                                 char buf[64], *t;
 
-                                t = strndupa(line, sep - line);
+                                t = strndupa_safe(line, sep - line);
                                 log_debug("Ignoring invalid field: \"%s\"",
                                           cellescape(buf, sizeof buf, t));
 
@@ -335,7 +335,7 @@ int journal_importer_process_data(JournalImporter *imp) {
                         if (!journal_field_valid(line, n - 1, true)) {
                                 char buf[64], *t;
 
-                                t = strndupa(line, n - 1);
+                                t = strndupa_safe(line, n - 1);
                                 log_debug("Ignoring invalid field: \"%s\"",
                                           cellescape(buf, sizeof buf, t));
 
index a3356c139a5081be35e5feb12fef3a0f5b7a091e..87b88f04d65221de9d1056811ee99f3c09c1e71d 100644 (file)
@@ -12,6 +12,7 @@
 #include "memory-util.h"
 #include "random-util.h"
 #include "strv.h"
+#include "unistd.h"
 
 static void *libfido2_dl = NULL;
 
@@ -1077,3 +1078,52 @@ finish:
                                "FIDO2 tokens not supported on this build.");
 #endif
 }
+
+int fido2_have_device(const char *device) {
+#if HAVE_LIBFIDO2
+        size_t allocated = 64, found = 0;
+        fido_dev_info_t *di = NULL;
+        int r;
+
+        /* Return == 0 if not devices are found, > 0 if at least one is found */
+
+        r = dlopen_libfido2();
+        if (r < 0)
+                return log_error_errno(r, "FIDO2 support is not installed.");
+
+        if (device) {
+                if (access(device, F_OK) < 0) {
+                        if (errno == ENOENT)
+                                return 0;
+
+                        return log_error_errno(errno, "Failed to determine whether device '%s' exists: %m", device);
+                }
+
+                return 1;
+        }
+
+        di = sym_fido_dev_info_new(allocated);
+        if (!di)
+                return log_oom();
+
+        r = sym_fido_dev_info_manifest(di, allocated, &found);
+        if (r == FIDO_ERR_INTERNAL) {
+                /* The library returns FIDO_ERR_INTERNAL when no devices are found. I wish it wouldn't. */
+                r = 0;
+                goto finish;
+        }
+        if (r != FIDO_OK) {
+                r = log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to enumerate FIDO2 devices: %s", sym_fido_strerr(r));
+                goto finish;
+        }
+
+        r = found;
+
+finish:
+        sym_fido_dev_info_free(&di, allocated);
+        return r;
+#else
+        return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP),
+                               "FIDO2 tokens not supported on this build.");
+#endif
+}
index 4ebf8ab775093f4ad7376435a41f17144c114d6a..c9cd505f34a2cc4655c9d421e950ebf86eb5210f 100644 (file)
@@ -119,3 +119,5 @@ int fido2_generate_hmac_hash(
 
 int fido2_list_devices(void);
 int fido2_find_device_auto(char **ret);
+
+int fido2_have_device(const char *device);
index 75fe4f34f7ae39121a21fb20b2ff47f5f90bfc08..cf83eb6bcaf39ca266c80fda9807c0844c985829 100644 (file)
@@ -190,7 +190,7 @@ static int field_set_test(const Set *fields, const char *name, size_t n) {
         if (!fields)
                 return 1;
 
-        s = strndupa(name, n);
+        s = strndupa_safe(name, n);
         return set_contains(fields, s);
 }
 
@@ -972,7 +972,7 @@ static int update_json_data_split(
         if (!journal_field_valid(data, fieldlen, true))
                 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Invalid field.");
 
-        name = strndupa(data, fieldlen);
+        name = strndupa_safe(data, fieldlen);
         if (output_fields && !set_contains(output_fields, name))
                 return 0;
 
index 19e16d93455c88662e040e97d19f10ef014e335d..06550306338581ebd7f312b342c3669351f572d2 100644 (file)
@@ -35,7 +35,7 @@ static int nscd_flush_cache_one(const char *database, usec_t end) {
         l = strlen(database);
         req_size = offsetof(struct nscdInvalidateRequest, dbname) + l + 1;
 
-        req = alloca(req_size);
+        req = alloca_safe(req_size);
         *req = (struct nscdInvalidateRequest) {
                 .version = 2,
                 .type = 10,
index 4bbad7e37be48abb80c63c156d83a19ccfd97c9c..90c347f8c0d5407871e69b3f49f9440179336440 100644 (file)
@@ -309,8 +309,8 @@ int show_man_page(const char *desc, bool null_stdio) {
         if (e) {
                 char *page = NULL, *section = NULL;
 
-                page = strndupa(desc, e - desc);
-                section = strndupa(e + 1, desc + k - e - 2);
+                page = strndupa_safe(desc, e - desc);
+                section = strndupa_safe(e + 1, desc + k - e - 2);
 
                 args[1] = section;
                 args[2] = page;
index d9cd8fb2b2d01445bf872cd613221b0c42719d70..a8693660fab2f4d823e17cdf7c33e4cf934b8f60 100644 (file)
@@ -250,6 +250,9 @@ int rm_rf_children(
                         ret = r;
         }
 
+        if (FLAGS_SET(flags, REMOVE_SYNCFS) && syncfs(dirfd(d)) < 0 && ret >= 0)
+                ret = -errno;
+
         return ret;
 }
 
index 577a2795e0f34f7834128a21f64e7ca5af82aa99..24fd9a2aa2d2650984ac81cde2f4be13604ba658 100644 (file)
@@ -14,6 +14,7 @@ typedef enum RemoveFlags {
         REMOVE_MISSING_OK       = 1 << 4, /* If the top-level directory is missing, ignore the ENOENT for it */
         REMOVE_CHMOD            = 1 << 5, /* chmod() for write access if we cannot delete or access something */
         REMOVE_CHMOD_RESTORE    = 1 << 6, /* Restore the old mode before returning */
+        REMOVE_SYNCFS           = 1 << 7, /* syncfs() the root of the specified directory after removing everything in it */
 } RemoveFlags;
 
 int unlinkat_harder(int dfd, const char *filename, int unlink_flags, RemoveFlags remove_flags);
index ca92a65efc517e8033e62ecc6389b4416324581c..da43fa22b9fc26050b07cca736f1781e8d64949a 100644 (file)
@@ -647,7 +647,8 @@ int mac_selinux_bind(int fd, const struct sockaddr *addr, socklen_t addrlen) {
         if (un->sun_path[0] == 0)
                 goto skipped;
 
-        path = strndupa(un->sun_path, addrlen - offsetof(struct sockaddr_un, sun_path));
+        path = strndupa_safe(un->sun_path,
+                             addrlen - offsetof(struct sockaddr_un, sun_path));
 
         /* Check for policy reload so 'label_hnd' is kept up-to-date by callbacks */
         mac_selinux_maybe_reload();
index 9d5a0ed86523d337919303bfcd48a8e5b1cd7df0..6a84d23db68e966ad813a5b07ecfc5e138ebb5c3 100644 (file)
@@ -151,7 +151,7 @@ static int tpm2_init(const char *device, struct tpm2_context *ret) {
 
                 param = strchr(device, ':');
                 if (param) {
-                        driver = strndupa(device, param - device);
+                        driver = strndupa_safe(device, param - device);
                         param++;
                 } else {
                         driver = "device";
index 5d5bf7f21d87b4dc9e924ca210e058a3340cad5d..2c07a1b7a8cc5df2fd95fd1399d60c87724dc12a 100644 (file)
@@ -114,7 +114,7 @@ int uid_range_add_str(UidRange **p, unsigned *n, const char *s) {
                 char *b;
                 uid_t end;
 
-                b = strndupa(s, t - s);
+                b = strndupa_safe(s, t - s);
                 r = parse_uid(b, &start);
                 if (r < 0)
                         return r;
index 29aa5c0c7c4abbc68ec04fe673b31915c461ba2a..dee6c4e5ee3d6df96bd81544ede9337e08111aa7 100644 (file)
@@ -435,6 +435,9 @@ void user_record_show(UserRecord *hr, bool show_full_group_info) {
         if (hr->password_change_now >= 0)
                 printf("Pas. Ch. Now: %s\n", yes_no(hr->password_change_now));
 
+        if (hr->drop_caches >= 0 || user_record_drop_caches(hr))
+                printf(" Drop Caches: %s\n", yes_no(user_record_drop_caches(hr)));
+
         if (!strv_isempty(hr->ssh_authorized_keys))
                 printf("SSH Pub. Key: %zu\n", strv_length(hr->ssh_authorized_keys));
 
index f4e509e13e1021d469b3503f012681ab838c2385..9b2029bfcfb0d214f5afbac9f7201cc3385717f1 100644 (file)
@@ -202,6 +202,7 @@ UserRecord* user_record_new(void) {
                 .pkcs11_protected_authentication_path_permitted = -1,
                 .fido2_user_presence_permitted = -1,
                 .fido2_user_verification_permitted = -1,
+                .drop_caches = -1,
         };
 
         return h;
@@ -1284,6 +1285,7 @@ static int dispatch_per_machine(const char *name, JsonVariant *variant, JsonDisp
                 { "luksPbkdfTimeCostUSec",      JSON_VARIANT_UNSIGNED,      json_dispatch_uint64,                 offsetof(UserRecord, luks_pbkdf_time_cost_usec),     0         },
                 { "luksPbkdfMemoryCost",        JSON_VARIANT_UNSIGNED,      json_dispatch_uint64,                 offsetof(UserRecord, luks_pbkdf_memory_cost),        0         },
                 { "luksPbkdfParallelThreads",   JSON_VARIANT_UNSIGNED,      json_dispatch_uint64,                 offsetof(UserRecord, luks_pbkdf_parallel_threads),   0         },
+                { "dropCaches",                 JSON_VARIANT_BOOLEAN,       json_dispatch_tristate,               offsetof(UserRecord, drop_caches),                   0         },
                 { "rateLimitIntervalUSec",      JSON_VARIANT_UNSIGNED,      json_dispatch_uint64,                 offsetof(UserRecord, ratelimit_interval_usec),       0         },
                 { "rateLimitBurst",             JSON_VARIANT_UNSIGNED,      json_dispatch_uint64,                 offsetof(UserRecord, ratelimit_burst),               0         },
                 { "enforcePasswordPolicy",      JSON_VARIANT_BOOLEAN,       json_dispatch_tristate,               offsetof(UserRecord, enforce_password_policy),       0         },
@@ -1406,11 +1408,11 @@ int user_record_build_image_path(UserStorage storage, const char *user_name_and_
                 return 0;
         }
 
-        z = strjoin("/home/", user_name_and_realm, suffix);
+        z = strjoin(get_home_root(), "/", user_name_and_realm, suffix);
         if (!z)
                 return -ENOMEM;
 
-        *ret = z;
+        *ret = path_simplify(z);
         return 1;
 }
 
@@ -1435,7 +1437,7 @@ static int user_record_augment(UserRecord *h, JsonDispatchFlags json_flags) {
                 return 0;
 
         if (!h->home_directory && !h->home_directory_auto) {
-                h->home_directory_auto = path_join("/home/", h->user_name);
+                h->home_directory_auto = path_join(get_home_root(), h->user_name);
                 if (!h->home_directory_auto)
                         return json_log_oom(h->json, json_flags);
         }
@@ -1620,7 +1622,7 @@ int user_record_load(UserRecord *h, JsonVariant *v, UserRecordLoadFlags load_fla
                 { "luksUuid",                   JSON_VARIANT_STRING,        json_dispatch_id128,                  offsetof(UserRecord, luks_uuid),                     0         },
                 { "fileSystemUuid",             JSON_VARIANT_STRING,        json_dispatch_id128,                  offsetof(UserRecord, file_system_uuid),              0         },
                 { "luksDiscard",                _JSON_VARIANT_TYPE_INVALID, json_dispatch_tristate,               offsetof(UserRecord, luks_discard),                  0         },
-                { "luksOfflineDiscard",         _JSON_VARIANT_TYPE_INVALID, json_dispatch_tristate,            offsetof(UserRecord, luks_offline_discard),          0         },
+                { "luksOfflineDiscard",         _JSON_VARIANT_TYPE_INVALID, json_dispatch_tristate,               offsetof(UserRecord, luks_offline_discard),          0         },
                 { "luksCipher",                 JSON_VARIANT_STRING,        json_dispatch_string,                 offsetof(UserRecord, luks_cipher),                   JSON_SAFE },
                 { "luksCipherMode",             JSON_VARIANT_STRING,        json_dispatch_string,                 offsetof(UserRecord, luks_cipher_mode),              JSON_SAFE },
                 { "luksVolumeKeySize",          JSON_VARIANT_UNSIGNED,      json_dispatch_uint64,                 offsetof(UserRecord, luks_volume_key_size),          0         },
@@ -1629,6 +1631,7 @@ int user_record_load(UserRecord *h, JsonVariant *v, UserRecordLoadFlags load_fla
                 { "luksPbkdfTimeCostUSec",      JSON_VARIANT_UNSIGNED,      json_dispatch_uint64,                 offsetof(UserRecord, luks_pbkdf_time_cost_usec),     0         },
                 { "luksPbkdfMemoryCost",        JSON_VARIANT_UNSIGNED,      json_dispatch_uint64,                 offsetof(UserRecord, luks_pbkdf_memory_cost),        0         },
                 { "luksPbkdfParallelThreads",   JSON_VARIANT_UNSIGNED,      json_dispatch_uint64,                 offsetof(UserRecord, luks_pbkdf_parallel_threads),   0         },
+                { "dropCaches",                 JSON_VARIANT_BOOLEAN,       json_dispatch_tristate,               offsetof(UserRecord, drop_caches),                   0         },
                 { "service",                    JSON_VARIANT_STRING,        json_dispatch_string,                 offsetof(UserRecord, service),                       JSON_SAFE },
                 { "rateLimitIntervalUSec",      JSON_VARIANT_UNSIGNED,      json_dispatch_uint64,                 offsetof(UserRecord, ratelimit_interval_usec),       0         },
                 { "rateLimitBurst",             JSON_VARIANT_UNSIGNED,      json_dispatch_uint64,                 offsetof(UserRecord, ratelimit_burst),               0         },
@@ -2021,6 +2024,16 @@ bool user_record_can_authenticate(UserRecord *h) {
         return !strv_isempty(h->hashed_password);
 }
 
+bool user_record_drop_caches(UserRecord *h) {
+        assert(h);
+
+        if (h->drop_caches >= 0)
+                return h->drop_caches;
+
+        /* By default drop caches on fscrypt, not otherwise. */
+        return user_record_storage(h) == USER_FSCRYPT;
+}
+
 uint64_t user_record_ratelimit_next_try(UserRecord *h) {
         assert(h);
 
index fa58dfdb6e6e33662e36403d3c47f76cdebaa9d5..975e3e175bcb75a42162c25bf515fa751ac898e1 100644 (file)
@@ -353,6 +353,7 @@ typedef struct UserRecord {
         int removable;
         int enforce_password_policy;
         int auto_login;
+        int drop_caches;
 
         uint64_t stop_delay_usec;   /* How long to leave systemd --user around on log-out */
         int kill_processes;         /* Whether to kill user processes forcibly on log-out */
@@ -419,6 +420,7 @@ int user_record_removable(UserRecord *h);
 usec_t user_record_ratelimit_interval_usec(UserRecord *h);
 uint64_t user_record_ratelimit_burst(UserRecord *h);
 bool user_record_can_authenticate(UserRecord *h);
+bool user_record_drop_caches(UserRecord *h);
 
 int user_record_build_image_path(UserStorage storage, const char *user_name_and_realm, char **ret);
 
index 07a1b96f6013189536b3598ef12505204f07154b..c34a08cf5780b257db79a18346fb11138b3cf37f 100644 (file)
@@ -258,8 +258,7 @@ static int varlink_new(Varlink **ret) {
 
                 .state = _VARLINK_STATE_INVALID,
 
-                .ucred.uid = UID_INVALID,
-                .ucred.gid = GID_INVALID,
+                .ucred = UCRED_INVALID,
 
                 .timestamp = USEC_INFINITY,
                 .timeout = VARLINK_DEFAULT_TIMEOUT_USEC
@@ -2077,7 +2076,7 @@ static int validate_connection(VarlinkServer *server, const struct ucred *ucred)
         return 1;
 }
 
-static int count_connection(VarlinkServer *server, struct ucred *ucred) {
+static int count_connection(VarlinkServer *server, const struct ucred *ucred) {
         unsigned c;
         int r;
 
@@ -2106,8 +2105,8 @@ static int count_connection(VarlinkServer *server, struct ucred *ucred) {
 
 int varlink_server_add_connection(VarlinkServer *server, int fd, Varlink **ret) {
         _cleanup_(varlink_unrefp) Varlink *v = NULL;
+        struct ucred ucred = UCRED_INVALID;
         bool ucred_acquired;
-        struct ucred ucred;
         int r;
 
         assert_return(server, -EINVAL);
index 3f6a2f0228264a6060e77b634fa58b8664a6d533..3f4c72826db13ea2138a729cadd6200032c45f8a 100644 (file)
 #include "errno-util.h"
 #include "fd-util.h"
 #include "log.h"
+#include "path-util.h"
 #include "string-util.h"
 #include "time-util.h"
 #include "watchdog.h"
 
 static int watchdog_fd = -1;
-static char *watchdog_device = NULL;
-static usec_t watchdog_timeout = USEC_INFINITY;
+static char *watchdog_device;
+static usec_t watchdog_timeout; /* 0 â†’ close device and USEC_INFINITY â†’ don't change timeout */
 static usec_t watchdog_last_ping = USEC_INFINITY;
 
+static int watchdog_set_enable(bool enable) {
+        int flags = enable ? WDIOS_ENABLECARD : WDIOS_DISABLECARD;
+
+        assert(watchdog_fd >= 0);
+
+        if (ioctl(watchdog_fd, WDIOC_SETOPTIONS, &flags) < 0) {
+                if (!enable)
+                        return log_warning_errno(errno, "Failed to disable hardware watchdog, ignoring: %m");
+
+                /* ENOTTY means the watchdog is always enabled so we're fine */
+                log_full_errno(ERRNO_IS_NOT_SUPPORTED(errno) ? LOG_DEBUG : LOG_WARNING, errno,
+                               "Failed to enable hardware watchdog, ignoring: %m");
+                if (!ERRNO_IS_NOT_SUPPORTED(errno))
+                        return -errno;
+        }
+
+        return 0;
+}
+
+static int watchdog_get_timeout(void) {
+        int sec = 0;
+
+        assert(watchdog_fd >= 0);
+
+        if (ioctl(watchdog_fd, WDIOC_GETTIMEOUT, &sec) < 0)
+                return -errno;
+
+        assert(sec > 0);
+        watchdog_timeout = sec * USEC_PER_SEC;
+
+        return 0;
+}
+
+static int watchdog_set_timeout(void) {
+        usec_t t;
+        int sec;
+
+        assert(watchdog_fd >= 0);
+        assert(timestamp_is_set(watchdog_timeout));
+
+        t = DIV_ROUND_UP(watchdog_timeout, USEC_PER_SEC);
+        sec = MIN(t, (usec_t) INT_MAX); /* Saturate */
+
+        if (ioctl(watchdog_fd, WDIOC_SETTIMEOUT, &sec) < 0)
+                return -errno;
+
+        assert(sec > 0);/*  buggy driver ? */
+        watchdog_timeout = sec * USEC_PER_SEC;
+
+        return 0;
+}
+
+static int watchdog_ping_now(void) {
+        assert(watchdog_fd >= 0);
+
+        if (ioctl(watchdog_fd, WDIOC_KEEPALIVE, 0) < 0)
+                return log_warning_errno(errno, "Failed to ping hardware watchdog, ignoring: %m");
+
+        watchdog_last_ping = now(clock_boottime_or_monotonic());
+
+        return 0;
+}
+
 static int update_timeout(void) {
+        int r;
+
+        assert(watchdog_timeout > 0);
+
         if (watchdog_fd < 0)
                 return 0;
-        if (watchdog_timeout == USEC_INFINITY)
-                return 0;
 
-        if (watchdog_timeout == 0) {
-                int flags;
+        if (watchdog_timeout != USEC_INFINITY) {
+                r = watchdog_set_timeout();
+                if (r < 0) {
+                        if (!ERRNO_IS_NOT_SUPPORTED(r))
+                                return log_error_errno(r, "Failed to set timeout to %s: %m",
+                                                       FORMAT_TIMESPAN(watchdog_timeout, 0));
 
-                flags = WDIOS_DISABLECARD;
-                if (ioctl(watchdog_fd, WDIOC_SETOPTIONS, &flags) < 0)
-                        return log_warning_errno(errno, "Failed to disable hardware watchdog, ignoring: %m");
-        } else {
-                int sec, flags;
-                usec_t t;
-
-                t = DIV_ROUND_UP(watchdog_timeout, USEC_PER_SEC);
-                sec = MIN(t, (usec_t) INT_MAX); /* Saturate */
-                if (ioctl(watchdog_fd, WDIOC_SETTIMEOUT, &sec) < 0)
-                        return log_warning_errno(errno, "Failed to set timeout to %is, ignoring: %m", sec);
-
-                /* Just in case the driver is buggy */
-                assert(sec > 0);
-
-                /* watchdog_timeout stores the actual timeout used by the HW */
-                watchdog_timeout = sec * USEC_PER_SEC;
-                log_info("Set hardware watchdog to %s.", FORMAT_TIMESPAN(watchdog_timeout, 0));
-
-                flags = WDIOS_ENABLECARD;
-                if (ioctl(watchdog_fd, WDIOC_SETOPTIONS, &flags) < 0) {
-                        /* ENOTTY means the watchdog is always enabled so we're fine */
-                        log_full_errno(ERRNO_IS_NOT_SUPPORTED(errno) ? LOG_DEBUG : LOG_WARNING, errno,
-                                       "Failed to enable hardware watchdog, ignoring: %m");
-                        if (!ERRNO_IS_NOT_SUPPORTED(errno))
-                                return -errno;
+                        log_info("Modifying watchdog timeout is not supported, reusing the programmed timeout.");
+                        watchdog_timeout = USEC_INFINITY;
                 }
+        }
 
-                if (ioctl(watchdog_fd, WDIOC_KEEPALIVE, 0) < 0)
-                        return log_warning_errno(errno, "Failed to ping hardware watchdog, ignoring: %m");
-
-                watchdog_last_ping = now(clock_boottime_or_monotonic());
+        if (watchdog_timeout == USEC_INFINITY) {
+                r = watchdog_get_timeout();
+                if (r < 0)
+                        return log_error_errno(r, "Failed to query watchdog HW timeout: %m");
         }
 
-        return 0;
+        r = watchdog_set_enable(true);
+        if (r < 0)
+                return r;
+
+        log_info("Watchdog running with a timeout of %s.", FORMAT_TIMESPAN(watchdog_timeout, 0));
+
+        return watchdog_ping_now();
 }
 
 static int open_watchdog(void) {
         struct watchdog_info ident;
         const char *fn;
+        int r;
 
         if (watchdog_fd >= 0)
                 return 0;
 
-        fn = watchdog_device ?: "/dev/watchdog";
+        /* Let's prefer new-style /dev/watchdog0 (i.e. kernel 3.5+) over classic /dev/watchdog. The former
+         * has the benefit that we can easily find the matching directory in sysfs from it, as the relevant
+         * sysfs attributes can only be found via /sys/dev/char/<major>:<minor> if the new-style device
+         * major/minor is used, not the old-style. */
+        fn = !watchdog_device || path_equal(watchdog_device, "/dev/watchdog") ?
+                "/dev/watchdog0" : watchdog_device;
+
         watchdog_fd = open(fn, O_WRONLY|O_CLOEXEC);
         if (watchdog_fd < 0)
                 return log_debug_errno(errno, "Failed to open watchdog device %s, ignoring: %m", fn);
@@ -85,7 +145,11 @@ static int open_watchdog(void) {
                          ident.firmware_version,
                          fn);
 
-        return update_timeout();
+        r = update_timeout();
+        if (r < 0)
+                watchdog_close(true);
+
+        return r;
 }
 
 int watchdog_set_device(const char *path) {
@@ -102,21 +166,38 @@ int watchdog_set_device(const char *path) {
 }
 
 int watchdog_setup(usec_t timeout) {
+        usec_t previous_timeout;
+        int r;
+
+        /* timeout=0 closes the device whereas passing timeout=USEC_INFINITY
+         * opens it (if needed) without configuring any particular timeout and
+         * thus reuses the programmed value (therefore it's a nop if the device
+         * is already opened).
+         */
+
+        if (timeout == 0) {
+                watchdog_close(true);
+                return 0;
+        }
+
+        /* Let's shortcut duplicated requests */
+        if (watchdog_fd >= 0 && (timeout == watchdog_timeout || timeout == USEC_INFINITY))
+                return 0;
 
         /* Initialize the watchdog timeout with the caller value. This value is
          * going to be updated by update_timeout() with the closest value
          * supported by the driver */
+        previous_timeout = watchdog_timeout;
         watchdog_timeout = timeout;
 
-        /* If we didn't open the watchdog yet and didn't get any explicit
-         * timeout value set, don't do anything */
-        if (watchdog_fd < 0 && watchdog_timeout == USEC_INFINITY)
-                return 0;
-
         if (watchdog_fd < 0)
                 return open_watchdog();
 
-        return update_timeout();
+        r = update_timeout();
+        if (r < 0)
+                watchdog_timeout = previous_timeout;
+
+        return r;
 }
 
 usec_t watchdog_runtime_wait(void) {
@@ -138,7 +219,7 @@ usec_t watchdog_runtime_wait(void) {
 int watchdog_ping(void) {
         usec_t ntime;
 
-        if (!timestamp_is_set(watchdog_timeout))
+        if (watchdog_timeout == 0)
                 return 0;
 
         if (watchdog_fd < 0)
@@ -155,24 +236,20 @@ int watchdog_ping(void) {
                         return 0;
         }
 
-        if (ioctl(watchdog_fd, WDIOC_KEEPALIVE, 0) < 0)
-                return log_warning_errno(errno, "Failed to ping hardware watchdog, ignoring: %m");
-
-        watchdog_last_ping = ntime;
-        return 0;
+        return watchdog_ping_now();
 }
 
 void watchdog_close(bool disarm) {
+
+        /* Once closed, pinging the device becomes a NOP and we request a new
+         * call to watchdog_setup() to open the device again. */
+        watchdog_timeout = 0;
+
         if (watchdog_fd < 0)
                 return;
 
         if (disarm) {
-                int flags;
-
-                /* Explicitly disarm it */
-                flags = WDIOS_DISABLECARD;
-                if (ioctl(watchdog_fd, WDIOC_SETOPTIONS, &flags) < 0)
-                        log_warning_errno(errno, "Failed to disable hardware watchdog, ignoring: %m");
+                (void) watchdog_set_enable(false);
 
                 /* To be sure, use magic close logic, too */
                 for (;;) {
@@ -189,8 +266,4 @@ void watchdog_close(bool disarm) {
         }
 
         watchdog_fd = safe_close(watchdog_fd);
-
-        /* Once closed, pinging the device becomes a NOP and we request a new
-         * call to watchdog_setup() to open the device again. */
-        watchdog_timeout = USEC_INFINITY;
 }
index 09fc339ab1d486620b0a124cce704ce0511faaca..881d4e471e9bb00e41431c4128423fe7f0905c8d 100644 (file)
 #include <sys/types.h>
 #include <unistd.h>
 
+#if HAVE_VALGRIND_MEMCHECK_H
+#include <valgrind/memcheck.h>
+#endif
+
 #include "sd-device.h"
 
 #include "alloc-util.h"
@@ -409,6 +413,10 @@ static int delete_loopback(const char *device) {
                         return -EBUSY; /* propagate original error */
                 }
 
+#if HAVE_VALGRIND_MEMCHECK_H
+                VALGRIND_MAKE_MEM_DEFINED(&info, sizeof(info));
+#endif
+
                 if (FLAGS_SET(info.lo_flags, LO_FLAGS_AUTOCLEAR)) /* someone else already set LO_FLAGS_AUTOCLEAR for us? fine by us */
                         return -EBUSY; /* propagate original error */
 
@@ -434,6 +442,10 @@ static int delete_loopback(const char *device) {
                 return 1;
         }
 
+#if HAVE_VALGRIND_MEMCHECK_H
+        VALGRIND_MAKE_MEM_DEFINED(&info, sizeof(info));
+#endif
+
         /* Linux makes LOOP_CLR_FD succeed whenever LO_FLAGS_AUTOCLEAR is set without actually doing
          * anything. Very confusing. Let's hence not claim we did anything in this case. */
         if (FLAGS_SET(info.lo_flags, LO_FLAGS_AUTOCLEAR))
index be0be91f3e46f05b9a0b48b77d777c7541fe5c24..aba483449a92d6a240546156a6b2ce22bb2e0ceb 100644 (file)
@@ -438,7 +438,8 @@ static int resolve_remote(Connection *c) {
 
         service = strrchr(arg_remote_host, ':');
         if (service) {
-                node = strndupa(arg_remote_host, service - arg_remote_host);
+                node = strndupa_safe(arg_remote_host,
+                                     service - arg_remote_host);
                 service++;
         } else {
                 node = arg_remote_host;
index f3889782bc0d1b70304edf9da1b6447779630e51..0e23c84e64c517e8bf5f0c3722de37201a15e10f 100644 (file)
@@ -39,44 +39,151 @@ enum {
         SD_DHCP6_CLIENT_EVENT_INFORMATION_REQUEST       = 13,
 };
 
+/* https://www.iana.org/assignments/dhcpv6-parameters/dhcpv6-parameters.xhtml#dhcpv6-parameters-2 */
 enum {
-        SD_DHCP6_OPTION_CLIENTID                   = 1,
-        SD_DHCP6_OPTION_SERVERID                   = 2,
-        SD_DHCP6_OPTION_IA_NA                      = 3,
-        SD_DHCP6_OPTION_IA_TA                      = 4,
-        SD_DHCP6_OPTION_IAADDR                     = 5,
-        SD_DHCP6_OPTION_ORO                        = 6,
-        SD_DHCP6_OPTION_PREFERENCE                 = 7,
-        SD_DHCP6_OPTION_ELAPSED_TIME               = 8,
-        SD_DHCP6_OPTION_RELAY_MSG                  = 9,
+        SD_DHCP6_OPTION_CLIENTID                   = 1,  /* RFC 8415 */
+        SD_DHCP6_OPTION_SERVERID                   = 2,  /* RFC 8415 */
+        SD_DHCP6_OPTION_IA_NA                      = 3,  /* RFC 8415 */
+        SD_DHCP6_OPTION_IA_TA                      = 4,  /* RFC 8415 */
+        SD_DHCP6_OPTION_IAADDR                     = 5,  /* RFC 8415 */
+        SD_DHCP6_OPTION_ORO                        = 6,  /* RFC 8415 */
+        SD_DHCP6_OPTION_PREFERENCE                 = 7,  /* RFC 8415 */
+        SD_DHCP6_OPTION_ELAPSED_TIME               = 8,  /* RFC 8415 */
+        SD_DHCP6_OPTION_RELAY_MSG                  = 9,  /* RFC 8415 */
         /* option code 10 is unassigned */
-        SD_DHCP6_OPTION_AUTH                       = 11,
-        SD_DHCP6_OPTION_UNICAST                    = 12,
-        SD_DHCP6_OPTION_STATUS_CODE                = 13,
-        SD_DHCP6_OPTION_RAPID_COMMIT               = 14,
-        SD_DHCP6_OPTION_USER_CLASS                 = 15,
-        SD_DHCP6_OPTION_VENDOR_CLASS               = 16,
-        SD_DHCP6_OPTION_VENDOR_OPTS                = 17,
-        SD_DHCP6_OPTION_INTERFACE_ID               = 18,
-        SD_DHCP6_OPTION_RECONF_MSG                 = 19,
-        SD_DHCP6_OPTION_RECONF_ACCEPT              = 20,
-
+        SD_DHCP6_OPTION_AUTH                       = 11,  /* RFC 8415 */
+        SD_DHCP6_OPTION_UNICAST                    = 12,  /* RFC 8415 */
+        SD_DHCP6_OPTION_STATUS_CODE                = 13,  /* RFC 8415 */
+        SD_DHCP6_OPTION_RAPID_COMMIT               = 14,  /* RFC 8415 */
+        SD_DHCP6_OPTION_USER_CLASS                 = 15,  /* RFC 8415 */
+        SD_DHCP6_OPTION_VENDOR_CLASS               = 16,  /* RFC 8415 */
+        SD_DHCP6_OPTION_VENDOR_OPTS                = 17,  /* RFC 8415 */
+        SD_DHCP6_OPTION_INTERFACE_ID               = 18,  /* RFC 8415 */
+        SD_DHCP6_OPTION_RECONF_MSG                 = 19,  /* RFC 8415 */
+        SD_DHCP6_OPTION_RECONF_ACCEPT              = 20,  /* RFC 8415 */
+        SD_DHCP6_OPTION_SIP_SERVER_DOMAIN_NAME     = 21,  /* RFC 3319 */
+        SD_DHCP6_OPTION_SIP_SERVER_ADDRESS         = 22,  /* RFC 3319 */
         SD_DHCP6_OPTION_DNS_SERVERS                = 23,  /* RFC 3646 */
         SD_DHCP6_OPTION_DOMAIN_LIST                = 24,  /* RFC 3646 */
-        SD_DHCP6_OPTION_IA_PD                      = 25,  /* RFC 3633, prefix delegation */
-        SD_DHCP6_OPTION_IA_PD_PREFIX               = 26,  /* RFC 3633, prefix delegation */
-
+        SD_DHCP6_OPTION_IA_PD                      = 25,  /* RFC 3633, RFC 8415 */
+        SD_DHCP6_OPTION_IA_PD_PREFIX               = 26,  /* RFC 3633, RFC 8415 */
+        SD_DHCP6_OPTION_NIS_SERVERS                = 27,  /* RFC 3898 */
+        SD_DHCP6_OPTION_NISP_SERVERS               = 28,  /* RFC 3898 */
+        SD_DHCP6_OPTION_NIS_DOMAIN_NAME            = 29,  /* RFC 3898 */
+        SD_DHCP6_OPTION_NISP_DOMAIN_NAME           = 30,  /* RFC 3898 */
         SD_DHCP6_OPTION_SNTP_SERVERS               = 31,  /* RFC 4075, deprecated */
-        SD_DHCP6_OPTION_INFORMATION_REFRESH_TIME   = 32,  /* RFC 8415, sec. 21.23 */
-
+        SD_DHCP6_OPTION_INFORMATION_REFRESH_TIME   = 32,  /* RFC 4242, 8415, sec. 21.23 */
+        SD_DHCP6_OPTION_BCMCS_SERVER_D             = 33,  /* RFC 4280 */
+        SD_DHCP6_OPTION_BCMCS_SERVER_A             = 34,  /* RFC 4280 */
         /* option code 35 is unassigned */
-
-        SD_DHCP6_OPTION_FQDN                       = 39,  /* RFC 4704 */
-
+        SD_DHCP6_OPTION_GEOCONF_CIVIC              = 36,  /* RFC 4776 */
+        SD_DHCP6_OPTION_REMOTE_ID                  = 37,  /* RFC 4649 */
+        SD_DHCP6_OPTION_SUBSCRIBER_ID              = 38,  /* RFC 4580 */
+        SD_DHCP6_OPTION_CLIENT_FQDN                = 39,  /* RFC 4704 */
+        SD_DHCP6_OPTION_PANA_AGENT                 = 40,  /* RFC 5192 */
+        SD_DHCP6_OPTION_NEW_POSIX_TIMEZONE         = 41,  /* RFC 4833 */
+        SD_DHCP6_OPTION_NEW_TZDB_TIMEZONE          = 42,  /* RFC 4833 */
+        SD_DHCP6_OPTION_ERO                        = 43,  /* RFC 4994 */
+        SD_DHCP6_OPTION_LQ_QUERY                   = 44,  /* RFC 5007 */
+        SD_DHCP6_OPTION_CLIENT_DATA                = 45,  /* RFC 5007 */
+        SD_DHCP6_OPTION_CLT_TIME                   = 46,  /* RFC 5007 */
+        SD_DHCP6_OPTION_LQ_RELAY_DATA              = 47,  /* RFC 5007 */
+        SD_DHCP6_OPTION_LQ_CLIENT_LINK             = 48,  /* RFC 5007 */
+        SD_DHCP6_OPTION_MIP6_HNIDF                 = 49,  /* RFC 6610 */
+        SD_DHCP6_OPTION_MIP6_VDINF                 = 50,  /* RFC 6610 */
+        SD_DHCP6_OPTION_V6_LOST                    = 51,  /* RFC 5223 */
+        SD_DHCP6_OPTION_CAPWAP_AC_V6               = 52,  /* RFC 5417 */
+        SD_DHCP6_OPTION_RELAY_ID                   = 53,  /* RFC 5460 */
+        SD_DHCP6_OPTION_IPV6_ADDRESS_MOS           = 54,  /* RFC 5678 */
+        SD_DHCP6_OPTION_IPV6_FQDN_MOS              = 55,  /* RFC 5678 */
         SD_DHCP6_OPTION_NTP_SERVER                 = 56,  /* RFC 5908 */
-        SD_DHCP6_OPTION_MUD_URL                    = 112, /* RFC 8250 */
-
-        /* option codes 89-142 are unassigned */
+        SD_DHCP6_OPTION_V6_ACCESS_DOMAIN           = 57,  /* RFC 5986 */
+        SD_DHCP6_OPTION_SIP_UA_CS_LIST             = 58,  /* RFC 6011 */
+        SD_DHCP6_OPTION_BOOTFILE_URL               = 59,  /* RFC 5970 */
+        SD_DHCP6_OPTION_BOOTFILE_PARAM             = 60,  /* RFC 5970 */
+        SD_DHCP6_OPTION_CLIENT_ARCH_TYPE           = 61,  /* RFC 5970 */
+        SD_DHCP6_OPTION_NII                        = 62,  /* RFC 5970 */
+        SD_DHCP6_OPTION_GEOLOCATION                = 63,  /* RFC 6225 */
+        SD_DHCP6_OPTION_AFTR_NAME                  = 64,  /* RFC 6334 */
+        SD_DHCP6_OPTION_ERP_LOCAL_DOMAIN_NAME      = 65,  /* RFC 6440 */
+        SD_DHCP6_OPTION_RSOO                       = 66,  /* RFC 6422 */
+        SD_DHCP6_OPTION_PD_EXCLUDE                 = 67,  /* RFC 6603 */
+        SD_DHCP6_OPTION_VSS                        = 68,  /* RFC 6607 */
+        SD_DHCP6_OPTION_MIP6_IDINF                 = 69,  /* RFC 6610 */
+        SD_DHCP6_OPTION_MIP6_UDINF                 = 70,  /* RFC 6610 */
+        SD_DHCP6_OPTION_MIP6_HNP                   = 71,  /* RFC 6610 */
+        SD_DHCP6_OPTION_MIP6_HAA                   = 72,  /* RFC 6610 */
+        SD_DHCP6_OPTION_MIP6_HAF                   = 73,  /* RFC 6610 */
+        SD_DHCP6_OPTION_RDNSS_SELECTION            = 74,  /* RFC 6731 */
+        SD_DHCP6_OPTION_KRB_PRINCIPAL_NAME         = 75,  /* RFC 6784 */
+        SD_DHCP6_OPTION_KRB_REALM_NAME             = 76,  /* RFC 6784 */
+        SD_DHCP6_OPTION_KRB_DEFAULT_REALM_NAME     = 77,  /* RFC 6784 */
+        SD_DHCP6_OPTION_KRB_KDC                    = 78,  /* RFC 6784 */
+        SD_DHCP6_OPTION_CLIENT_LINKLAYER_ADDR      = 79,  /* RFC 6939 */
+        SD_DHCP6_OPTION_LINK_ADDRESS               = 80,  /* RFC 6977 */
+        SD_DHCP6_OPTION_RADIUS                     = 81,  /* RFC 7037 */
+        SD_DHCP6_OPTION_SOL_MAX_RT                 = 82,  /* RFC 7083, RFC 8415 */
+        SD_DHCP6_OPTION_INF_MAX_RT                 = 83,  /* RFC 7083, RFC 8415 */
+        SD_DHCP6_OPTION_ADDRSEL                    = 84,  /* RFC 7078 */
+        SD_DHCP6_OPTION_ADDRSEL_TABLE              = 85,  /* RFC 7078 */
+        SD_DHCP6_OPTION_V6_PCP_SERVER              = 86,  /* RFC 7291 */
+        SD_DHCP6_OPTION_DHCPV4_MSG                 = 87,  /* RFC 7341 */
+        SD_DHCP6_OPTION_DHCP4_O_DHCP6_SERVER       = 88,  /* RFC 7341 */
+        SD_DHCP6_OPTION_S46_RULE                   = 89,  /* RFC 7598 */
+        SD_DHCP6_OPTION_S46_BR                     = 90,  /* RFC 7598, RFC 8539 */
+        SD_DHCP6_OPTION_S46_DMR                    = 91,  /* RFC 7598 */
+        SD_DHCP6_OPTION_S46_V4V6BIND               = 92,  /* RFC 7598 */
+        SD_DHCP6_OPTION_S46_PORTPARAMS             = 93,  /* RFC 7598 */
+        SD_DHCP6_OPTION_S46_CONT_MAPE              = 94,  /* RFC 7598 */
+        SD_DHCP6_OPTION_S46_CONT_MAPT              = 95,  /* RFC 7598 */
+        SD_DHCP6_OPTION_S46_CONT_LW                = 96,  /* RFC 7598 */
+        SD_DHCP6_OPTION_4RD                        = 97,  /* RFC 7600 */
+        SD_DHCP6_OPTION_4RD_MAP_RULE               = 98,  /* RFC 7600 */
+        SD_DHCP6_OPTION_4RD_NON_MAP_RULE           = 99,  /* RFC 7600 */
+        SD_DHCP6_OPTION_LQ_BASE_TIME               = 100, /* RFC 7653 */
+        SD_DHCP6_OPTION_LQ_START_TIME              = 101, /* RFC 7653 */
+        SD_DHCP6_OPTION_LQ_END_TIME                = 102, /* RFC 7653 */
+        SD_DHCP6_OPTION_CAPTIVE_PORTAL             = 103, /* RFC 8910 */
+        SD_DHCP6_OPTION_MPL_PARAMETERS             = 104, /* RFC 7774 */
+        SD_DHCP6_OPTION_ANI_ATT                    = 105, /* RFC 7839 */
+        SD_DHCP6_OPTION_ANI_NETWORK_NAME           = 106, /* RFC 7839 */
+        SD_DHCP6_OPTION_ANI_AP_NAME                = 107, /* RFC 7839 */
+        SD_DHCP6_OPTION_ANI_AP_BSSID               = 108, /* RFC 7839 */
+        SD_DHCP6_OPTION_ANI_OPERATOR_ID            = 109, /* RFC 7839 */
+        SD_DHCP6_OPTION_ANI_OPERATOR_REALM         = 110, /* RFC 7839 */
+        SD_DHCP6_OPTION_S46_PRIORITY               = 111, /* RFC 8026 */
+        SD_DHCP6_OPTION_MUD_URL_V6                 = 112, /* RFC 8520 */
+        SD_DHCP6_OPTION_V6_PREFIX64                = 113, /* RFC 8115 */
+        SD_DHCP6_OPTION_F_BINDING_STATUS           = 114, /* RFC 8156 */
+        SD_DHCP6_OPTION_F_CONNECT_FLAGS            = 115, /* RFC 8156 */
+        SD_DHCP6_OPTION_F_DNS_REMOVAL_INFO         = 116, /* RFC 8156 */
+        SD_DHCP6_OPTION_F_DNS_HOST_NAME            = 117, /* RFC 8156 */
+        SD_DHCP6_OPTION_F_DNS_ZONE_NAME            = 118, /* RFC 8156 */
+        SD_DHCP6_OPTION_F_DNS_FLAGS                = 119, /* RFC 8156 */
+        SD_DHCP6_OPTION_F_EXPIRATION_TIME          = 120, /* RFC 8156 */
+        SD_DHCP6_OPTION_F_MAX_UNACKED_BNDUPD       = 121, /* RFC 8156 */
+        SD_DHCP6_OPTION_F_MCLT                     = 122, /* RFC 8156 */
+        SD_DHCP6_OPTION_F_PARTNER_LIFETIME         = 123, /* RFC 8156 */
+        SD_DHCP6_OPTION_F_PARTNER_LIFETIME_SENT    = 124, /* RFC 8156 */
+        SD_DHCP6_OPTION_F_PARTNER_DOWN_TIME        = 125, /* RFC 8156 */
+        SD_DHCP6_OPTION_F_PARTNER_RAW_CLT_TIME     = 126, /* RFC 8156 */
+        SD_DHCP6_OPTION_F_PROTOCOL_VERSION         = 127, /* RFC 8156 */
+        SD_DHCP6_OPTION_F_KEEPALIVE_TIME           = 128, /* RFC 8156 */
+        SD_DHCP6_OPTION_F_RECONFIGURE_DATA         = 129, /* RFC 8156 */
+        SD_DHCP6_OPTION_F_RELATIONSHIP_NAME        = 130, /* RFC 8156 */
+        SD_DHCP6_OPTION_F_SERVER_FLAGS             = 131, /* RFC 8156 */
+        SD_DHCP6_OPTION_F_SERVER_STATE             = 132, /* RFC 8156 */
+        SD_DHCP6_OPTION_F_START_TIME_OF_STATE      = 133, /* RFC 8156 */
+        SD_DHCP6_OPTION_F_STATE_EXPIRATION_TIME    = 134, /* RFC 8156 */
+        SD_DHCP6_OPTION_RELAY_PORT                 = 135, /* RFC 8357 */
+        SD_DHCP6_OPTION_V6_SZTP_REDIRECT           = 136, /* RFC 8572 */
+        SD_DHCP6_OPTION_S46_BIND_IPV6_PREFIX       = 137, /* RFC 8539 */
+        SD_DHCP6_OPTION_IA_LL                      = 138, /* RFC 8947 */
+        SD_DHCP6_OPTION_LLADDR                     = 139, /* RFC 8947 */
+        SD_DHCP6_OPTION_SLAP_QUAD                  = 140, /* RFC 8948 */
+        SD_DHCP6_OPTION_V6_DOTS_RI                 = 141, /* RFC 8973 */
+        SD_DHCP6_OPTION_V6_DOTS_ADDRESS            = 142, /* RFC 8973 */
+        SD_DHCP6_OPTION_IPV6_ADDRESS_ANDSF         = 143, /* RFC 6153 */
         /* option codes 144-65535 are unassigned */
 };
 
index 6bf56def403a8058ef4ebf343ac6c4beb148c7c7..f597c2c33daaf2714ebf7629e82b29debac8edb5 100644 (file)
@@ -91,7 +91,7 @@ int sd_radv_route_prefix_new(sd_radv_route_prefix **ret);
 sd_radv_route_prefix *sd_radv_route_prefix_ref(sd_radv_route_prefix *ra);
 sd_radv_route_prefix *sd_radv_route_prefix_unref(sd_radv_route_prefix *ra);
 
-int sd_radv_prefix_set_route_prefix(sd_radv_route_prefix *p, const struct in6_addr *in6_addr, unsigned char prefixlen);
+int sd_radv_route_prefix_set_prefix(sd_radv_route_prefix *p, const struct in6_addr *in6_addr, unsigned char prefixlen);
 int sd_radv_route_prefix_set_lifetime(sd_radv_route_prefix *p, uint32_t valid_lifetime);
 
 _SD_DEFINE_POINTER_CLEANUP_FUNC(sd_radv, sd_radv_unref);
index bf23c48662162708a31017e077c1195513b7e774..194766445719c4675d5131fe83fcb060a7a7ce48 100644 (file)
@@ -289,7 +289,7 @@ static int sysv_translate_facility(SysvStub *s, unsigned line, const char *name,
         }
 
         /* Strip ".sh" suffix from file name for comparison */
-        filename_no_sh = strdupa(filename);
+        filename_no_sh = strdupa_safe(filename);
         e = endswith(filename_no_sh, ".sh");
         if (e) {
                 *e = '\0';
index 23155b2d98b61580bf2a3208d97c90214a1cea8b..2bee2d5c1d6fc2c278d0ac60b6ab881da693b106 100644 (file)
@@ -76,11 +76,11 @@ int main(int argc, char* argv[]) {
         test_setup_logging(LOG_DEBUG);
 
         p = test_acpi_fpdt();
-        assert(p >= 0);
+        assert_se(p >= 0);
         q = test_efi_loader();
-        assert(q >= 0);
+        assert_se(q >= 0);
         r = test_boot_timestamps();
-        assert(r >= 0);
+        assert_se(r >= 0);
 
         if (p == 0 && q == 0 && r == 0)
                 return log_tests_skipped("access to firmware variables not possible");
index 2c5eb7313bd389154a2d4dd66fec5fcc4cb78b0b..bbaa7b3605e3000dc1b2789128f2e20a57880e02 100644 (file)
@@ -15,7 +15,7 @@
 #include "tests.h"
 
 static void test_policy_closed(const char *cgroup_path, BPFProgram **installed_prog) {
-        _cleanup_(bpf_program_unrefp) BPFProgram *prog = NULL;
+        _cleanup_(bpf_program_freep) BPFProgram *prog = NULL;
         unsigned wrong = 0;
         int r;
 
@@ -27,7 +27,7 @@ static void test_policy_closed(const char *cgroup_path, BPFProgram **installed_p
         r = bpf_devices_allow_list_static(prog, cgroup_path);
         assert_se(r >= 0);
 
-        r = bpf_devices_apply_policy(prog, CGROUP_DEVICE_POLICY_CLOSED, true, cgroup_path, installed_prog);
+        r = bpf_devices_apply_policy(&prog, CGROUP_DEVICE_POLICY_CLOSED, true, cgroup_path, installed_prog);
         assert_se(r >= 0);
 
         const char *s;
@@ -53,7 +53,7 @@ static void test_policy_closed(const char *cgroup_path, BPFProgram **installed_p
 }
 
 static void test_policy_strict(const char *cgroup_path, BPFProgram **installed_prog) {
-        _cleanup_(bpf_program_unrefp) BPFProgram *prog = NULL;
+        _cleanup_(bpf_program_freep) BPFProgram *prog = NULL;
         unsigned wrong = 0;
         int r;
 
@@ -71,7 +71,7 @@ static void test_policy_strict(const char *cgroup_path, BPFProgram **installed_p
         r = bpf_devices_allow_list_device(prog, cgroup_path, "/dev/zero", "w");
         assert_se(r >= 0);
 
-        r = bpf_devices_apply_policy(prog, CGROUP_DEVICE_POLICY_STRICT, true, cgroup_path, installed_prog);
+        r = bpf_devices_apply_policy(&prog, CGROUP_DEVICE_POLICY_STRICT, true, cgroup_path, installed_prog);
         assert_se(r >= 0);
 
         {
@@ -130,7 +130,7 @@ static void test_policy_strict(const char *cgroup_path, BPFProgram **installed_p
 }
 
 static void test_policy_allow_list_major(const char *pattern, const char *cgroup_path, BPFProgram **installed_prog) {
-        _cleanup_(bpf_program_unrefp) BPFProgram *prog = NULL;
+        _cleanup_(bpf_program_freep) BPFProgram *prog = NULL;
         unsigned wrong = 0;
         int r;
 
@@ -142,7 +142,7 @@ static void test_policy_allow_list_major(const char *pattern, const char *cgroup
         r = bpf_devices_allow_list_major(prog, cgroup_path, pattern, 'c', "rw");
         assert_se(r >= 0);
 
-        r = bpf_devices_apply_policy(prog, CGROUP_DEVICE_POLICY_STRICT, true, cgroup_path, installed_prog);
+        r = bpf_devices_apply_policy(&prog, CGROUP_DEVICE_POLICY_STRICT, true, cgroup_path, installed_prog);
         assert_se(r >= 0);
 
         /* /dev/null, /dev/full have major==1, /dev/tty has major==5 */
@@ -189,7 +189,7 @@ static void test_policy_allow_list_major(const char *pattern, const char *cgroup
 }
 
 static void test_policy_allow_list_major_star(char type, const char *cgroup_path, BPFProgram **installed_prog) {
-        _cleanup_(bpf_program_unrefp) BPFProgram *prog = NULL;
+        _cleanup_(bpf_program_freep) BPFProgram *prog = NULL;
         unsigned wrong = 0;
         int r;
 
@@ -201,7 +201,7 @@ static void test_policy_allow_list_major_star(char type, const char *cgroup_path
         r = bpf_devices_allow_list_major(prog, cgroup_path, "*", type, "rw");
         assert_se(r >= 0);
 
-        r = bpf_devices_apply_policy(prog, CGROUP_DEVICE_POLICY_STRICT, true, cgroup_path, installed_prog);
+        r = bpf_devices_apply_policy(&prog, CGROUP_DEVICE_POLICY_STRICT, true, cgroup_path, installed_prog);
         assert_se(r >= 0);
 
         {
@@ -220,7 +220,7 @@ static void test_policy_allow_list_major_star(char type, const char *cgroup_path
 }
 
 static void test_policy_empty(bool add_mismatched, const char *cgroup_path, BPFProgram **installed_prog) {
-        _cleanup_(bpf_program_unrefp) BPFProgram *prog = NULL;
+        _cleanup_(bpf_program_freep) BPFProgram *prog = NULL;
         unsigned wrong = 0;
         int r;
 
@@ -234,7 +234,7 @@ static void test_policy_empty(bool add_mismatched, const char *cgroup_path, BPFP
                 assert_se(r < 0);
         }
 
-        r = bpf_devices_apply_policy(prog, CGROUP_DEVICE_POLICY_STRICT, false, cgroup_path, installed_prog);
+        r = bpf_devices_apply_policy(&prog, CGROUP_DEVICE_POLICY_STRICT, false, cgroup_path, installed_prog);
         assert_se(r >= 0);
 
         {
@@ -282,7 +282,7 @@ int main(int argc, char *argv[]) {
         r = cg_get_path(SYSTEMD_CGROUP_CONTROLLER, cgroup, NULL, &controller_path);
         assert_se(r >= 0);
 
-        _cleanup_(bpf_program_unrefp) BPFProgram *prog = NULL;
+        _cleanup_(bpf_program_freep) BPFProgram *prog = NULL;
 
         test_policy_closed(cgroup, &prog);
         test_policy_strict(cgroup, &prog);
index 1e0ad177b9956616fa9e49b2677bb19e6860e4db..2e19db600e1bfdc79c1f3b4bb4fa37e9347aef6b 100644 (file)
@@ -24,7 +24,7 @@ int main(int argc, char *argv[]) {
 
         _cleanup_(rm_rf_physical_and_freep) char *runtime_dir = NULL;
         CGroupContext *cc = NULL;
-        _cleanup_(bpf_program_unrefp) BPFProgram *p = NULL;
+        _cleanup_(bpf_program_freep) BPFProgram *p = NULL;
         _cleanup_(manager_freep) Manager *m = NULL;
         Unit *u;
         char log_buf[65535];
@@ -56,10 +56,10 @@ int main(int argc, char *argv[]) {
         assert_se(runtime_dir = setup_fake_runtime_dir());
 
         r = bpf_program_new(BPF_PROG_TYPE_CGROUP_SKB, &p);
-        assert(r == 0);
+        assert_se(r == 0);
 
         r = bpf_program_add_instructions(p, exit_insn, ELEMENTSOF(exit_insn));
-        assert(r == 0);
+        assert_se(r == 0);
 
         if (getuid() != 0)
                 return log_tests_skipped("not running as root");
@@ -76,7 +76,7 @@ int main(int argc, char *argv[]) {
                 log_notice("BPF firewalling (though without BPF_F_ALLOW_MULTI) supported. Good.");
 
         r = bpf_program_load_kernel(p, log_buf, ELEMENTSOF(log_buf));
-        assert(r >= 0);
+        assert_se(r >= 0);
 
         if (test_custom_filter) {
                 zero(attr);
@@ -93,7 +93,7 @@ int main(int argc, char *argv[]) {
                 }
         }
 
-        p = bpf_program_unref(p);
+        p = bpf_program_free(p);
 
         /* The simple tests succeeded. Now let's try full unit-based use-case. */
 
@@ -158,8 +158,8 @@ int main(int argc, char *argv[]) {
                 return log_tests_skipped("Kernel doesn't support the necessary bpf bits (masked out via seccomp?)");
         assert_se(r >= 0);
 
-        assert(u->ip_bpf_ingress);
-        assert(u->ip_bpf_egress);
+        assert_se(u->ip_bpf_ingress);
+        assert_se(u->ip_bpf_egress);
 
         r = bpf_program_load_kernel(u->ip_bpf_ingress, log_buf, ELEMENTSOF(log_buf));
 
@@ -168,7 +168,7 @@ int main(int argc, char *argv[]) {
         log_notice("%s", log_buf);
         log_notice("-------");
 
-        assert(r >= 0);
+        assert_se(r >= 0);
 
         r = bpf_program_load_kernel(u->ip_bpf_egress, log_buf, ELEMENTSOF(log_buf));
 
@@ -177,7 +177,7 @@ int main(int argc, char *argv[]) {
         log_notice("%s", log_buf);
         log_notice("-------");
 
-        assert(r >= 0);
+        assert_se(r >= 0);
 
         assert_se(unit_start(u) >= 0);
 
index 86e05e23aba4303c143a64769802fcc0cb24b114..1765dc7a9be407fbc539e0cc5578c24244d7f861 100644 (file)
@@ -155,7 +155,7 @@ static int pin_programs(Unit *u, CGroupContext *cc, const Test *test_suite, size
         assert_se(paths_ret);
 
         for (size_t i = 0; i < test_suite_size; i++) {
-                _cleanup_(bpf_program_unrefp) BPFProgram *prog = NULL;
+                _cleanup_(bpf_program_freep) BPFProgram *prog = NULL;
                 _cleanup_free_ char *str = NULL;
 
                 r = bpf_foreign_test_to_string(test_suite[i].attach_type, test_suite[i].bpffs_path, &str);
index 0381ba1ee4feb24e47df3341a1d4c1e373556dc7..5aa1bfac0e5db003f5243d9433911b57045af2b7 100644 (file)
@@ -30,7 +30,7 @@ static void test_destroy_callback(void) {
         }
 
         r = sd_bus_request_name_async(bus, &slot, "org.freedesktop.systemd.test-bus-util", 0, callback, &n_called);
-        assert(r == 1);
+        assert_se(r == 1);
 
         assert_se(sd_bus_slot_get_destroy_callback(slot, NULL) == 0);
         assert_se(sd_bus_slot_get_destroy_callback(slot, &t) == 0);
@@ -41,9 +41,9 @@ static void test_destroy_callback(void) {
         assert_se(t == destroy_callback);
 
         /* Force cleanup so we can look at n_called */
-        assert(n_called == 0);
+        assert_se(n_called == 0);
         sd_bus_slot_unref(slot);
-        assert(n_called == 1);
+        assert_se(n_called == 1);
 }
 
 int main(int argc, char **argv) {
index 5d680f9b9a469e9d2b250daebc2f73442789fc10..750b9ea2ca205bd9cf5091ccbd1834ecf831073b 100644 (file)
@@ -40,7 +40,7 @@ static void _test_next(int line, const char *input, const char *new_tz, usec_t a
 
         old_tz = getenv("TZ");
         if (old_tz)
-                old_tz = strdupa(old_tz);
+                old_tz = strdupa_safe(old_tz);
 
         if (!isempty(new_tz))
                 new_tz = strjoina(":", new_tz);
@@ -58,7 +58,7 @@ static void _test_next(int line, const char *input, const char *new_tz, usec_t a
         if (expect != USEC_INFINITY)
                 assert_se(r >= 0 && u == expect);
         else
-                assert(r == -ENOENT);
+                assert_se(r == -ENOENT);
 
         calendar_spec_free(c);
 
index 94f15bfb213a9798754d84d3aa5e33e3e917901d..c5596bb6c3c2765324630ee4db8bf6a4dbebc6d3 100644 (file)
@@ -194,7 +194,7 @@ static void test_update_inherited_set(void) {
 
         assert_se(!capability_update_inherited_set(caps, set));
         assert_se(!cap_get_flag(caps, CAP_CHOWN, CAP_INHERITABLE, &fv));
-        assert(fv == CAP_SET);
+        assert_se(fv == CAP_SET);
 
         cap_free(caps);
 }
index c2adfa07ce02cc6eab869e36e254d014605ca15e..bc5eda61f8e8e9ed98498fb0e0610ac96011024b 100644 (file)
@@ -395,12 +395,12 @@ static void test_cg_get_keyed_attribute(void) {
 
         assert_se(cg_get_keyed_attribute("cpu", "/init.scope", "cpu.stat", STRV_MAKE("usage_usec", "no_such_attr"), vals3) == -ENXIO);
         assert_se(cg_get_keyed_attribute_graceful("cpu", "/init.scope", "cpu.stat", STRV_MAKE("usage_usec", "no_such_attr"), vals3) == 1);
-        assert(vals3[0] && !vals3[1]);
+        assert_se(vals3[0] && !vals3[1]);
         free(vals3[0]);
 
         assert_se(cg_get_keyed_attribute("cpu", "/init.scope", "cpu.stat", STRV_MAKE("usage_usec", "usage_usec"), vals3) == -ENXIO);
         assert_se(cg_get_keyed_attribute_graceful("cpu", "/init.scope", "cpu.stat", STRV_MAKE("usage_usec", "usage_usec"), vals3) == 1);
-        assert(vals3[0] && !vals3[1]);
+        assert_se(vals3[0] && !vals3[1]);
         free(vals3[0]);
 
         assert_se(cg_get_keyed_attribute("cpu", "/init.scope", "cpu.stat",
index 5f53eba101a15019b1d4cc696ec7a16b8b19d9dd..9e50c5c7490875345c8392e6912de93abe91a160 100644 (file)
@@ -34,8 +34,8 @@ static int parse_argv(int argc, char *argv[]) {
 
         int c;
 
-        assert(argc >= 0);
-        assert(argv);
+        assert_se(argc >= 0);
+        assert_se(argv);
 
         while ((c = getopt_long(argc, argv, "", options, NULL)) >= 0)
                 switch (c) {
@@ -103,9 +103,9 @@ static int run(int argc, char **argv) {
                 else {
                         log_info("→ %s", p);
                         if (arg_open)
-                                assert(fd >= 0);
+                                assert_se(fd >= 0);
                         else
-                                assert(fd == -1);
+                                assert_se(fd == -1);
                 }
         }
 
index 62776086c287b187bf60294c35d75d1ef00da699..d7cd63da815f0fdea7e40be79a50d03304397077 100644 (file)
@@ -689,12 +689,12 @@ static void test_condition_test_group(void) {
         free(gid);
 
         ngroups_max = sysconf(_SC_NGROUPS_MAX);
-        assert(ngroups_max > 0);
+        assert_se(ngroups_max > 0);
 
         gids = newa(gid_t, ngroups_max);
 
         ngroups = getgroups(ngroups_max, gids);
-        assert(ngroups >= 0);
+        assert_se(ngroups >= 0);
 
         max_gid = getgid();
         for (i = 0; i < ngroups; i++) {
index 0cfc883d66885d2c951e4ba99089f7c710fbb0bf..c07b93950620e83330d28a0898c1d58b0e46fa42 100644 (file)
@@ -256,7 +256,7 @@ static void test_cpu_set_to_from_dbus(void) {
 
         assert_se(allocated <= sizeof expected);
         assert_se(allocated >= DIV_ROUND_UP(201u, 8u)); /* We need at least 201 bits for our mask */
-        assert(memcmp(array, expected, allocated) == 0);
+        assert_se(memcmp(array, expected, allocated) == 0);
 
         assert_se(cpu_set_from_dbus(array, allocated, &c2) == 0);
         assert_se(c2.set);
@@ -268,7 +268,7 @@ static void test_cpus_in_affinity_mask(void) {
         int r;
 
         r = cpus_in_affinity_mask();
-        assert(r > 0);
+        assert_se(r > 0);
         log_info("cpus_in_affinity_mask: %d", r);
 }
 
index 413e8cd860e734972a56923710789f369e895cfd..3fd318653c2291cf64508c0d0c7befdc30ee5565 100644 (file)
@@ -58,8 +58,8 @@ static void test_xescape_full(bool eight_bits) {
                 log_info("%02d: <%s>", i, q);
                 if (i > 0)
                         assert_se(endswith(q, "."));
-                assert(strlen(q) <= i);
-                assert(strlen(q) + 3 >= strlen(t));
+                assert_se(strlen(q) <= i);
+                assert_se(strlen(q) + 3 >= strlen(t));
         }
 }
 
index 4c11f54cef5e8ca714716b37d07889e964179b04..ae740218b2dbb6617d646cb3ce9c0e63d7322f1d 100644 (file)
@@ -26,22 +26,22 @@ static void *ignore_stdout_args[] = { &here, &here2, &here3 };
 
 /* noop handlers, just check that arguments are passed correctly */
 static int ignore_stdout_func(int fd, void *arg) {
-        assert(fd >= 0);
-        assert(arg == &here);
+        assert_se(fd >= 0);
+        assert_se(arg == &here);
         safe_close(fd);
 
         return 0;
 }
 static int ignore_stdout_func2(int fd, void *arg) {
-        assert(fd >= 0);
-        assert(arg == &here2);
+        assert_se(fd >= 0);
+        assert_se(arg == &here2);
         safe_close(fd);
 
         return 0;
 }
 static int ignore_stdout_func3(int fd, void *arg) {
-        assert(fd >= 0);
-        assert(arg == &here3);
+        assert_se(fd >= 0);
+        assert_se(arg == &here3);
         safe_close(fd);
 
         return 0;
index 98989f405a8dd2f0704f8ef3c891f289280d671c..b9c1dc72c2393c1298f56b9c597f769dd306769f 100644 (file)
@@ -174,7 +174,7 @@ static bool check_user_has_group_with_same_name(const char *name) {
         struct passwd *p;
         struct group *g;
 
-        assert(name);
+        assert_se(name);
 
         p = getpwnam(name);
         if (!p ||
@@ -510,8 +510,8 @@ static int on_spawn_io(sd_event_source *s, int fd, uint32_t revents, void *userd
         char buf[4096];
         ssize_t l;
 
-        assert(s);
-        assert(fd >= 0);
+        assert_se(s);
+        assert_se(fd >= 0);
 
         l = read(fd, buf, sizeof(buf) - 1);
         if (l < 0) {
@@ -538,7 +538,7 @@ reenable:
 static int on_spawn_timeout(sd_event_source *s, uint64_t usec, void *userdata) {
         pid_t *pid = userdata;
 
-        assert(pid);
+        assert_se(pid);
 
         (void) kill(*pid, SIGKILL);
 
@@ -548,7 +548,7 @@ static int on_spawn_timeout(sd_event_source *s, uint64_t usec, void *userdata) {
 static int on_spawn_sigchld(sd_event_source *s, const siginfo_t *si, void *userdata) {
         int ret = -EIO;
 
-        assert(si);
+        assert_se(si);
 
         if (si->si_code == CLD_EXITED)
                 ret = si->si_status;
@@ -568,8 +568,8 @@ static int find_libraries(const char *exec, char ***ret) {
         pid_t pid;
         int r;
 
-        assert(exec);
-        assert(ret);
+        assert_se(exec);
+        assert_se(ret);
 
         assert_se(sigprocmask_many(SIG_BLOCK, NULL, SIGCHLD, -1) >= 0);
 
@@ -653,7 +653,7 @@ static void test_exec_mount_apivfs(Manager *m) {
         _cleanup_strv_free_ char **libraries = NULL, **libraries_test = NULL;
         int r;
 
-        assert(user_runtime_unit_dir);
+        assert_se(user_runtime_unit_dir);
 
         r = find_executable("touch", &fullpath_touch);
         if (r < 0) {
index fa8a66df042bcbff72849c6a1f2b58c89162bcfb..5c266c0c9adaf52082ca896a7efb3fc45a620779 100644 (file)
@@ -241,7 +241,7 @@ static void test_merge_env_file(void) {
                                 "zzzz=${foobar:-${nothing}}\n"
                                 "zzzzz=${nothing:+${nothing}}\n"
                                 , WRITE_STRING_FILE_AVOID_NEWLINE);
-        assert(r >= 0);
+        assert_se(r >= 0);
 
         r = merge_env_file(&a, NULL, t);
         assert_se(r >= 0);
@@ -305,7 +305,7 @@ static void test_merge_env_file_invalid(void) {
                                 "#\n"
                                 "\n\n"                  /* empty line */
                                 , WRITE_STRING_FILE_AVOID_NEWLINE);
-        assert(r >= 0);
+        assert_se(r >= 0);
 
         r = merge_env_file(&a, NULL, t);
         assert_se(r >= 0);
index d2843cfab73da20a52234a7f98f53e327f9efad8..f22bc3c5bcce903877ef187e125334a551190861 100644 (file)
@@ -47,8 +47,8 @@ static void test_v6(FirewallContext *ctx) {
 }
 
 static union in_addr_union *parse_addr(const char *str, union in_addr_union *u) {
-        assert(str);
-        assert(u);
+        assert_se(str);
+        assert_se(u);
         assert_se(in_addr_from_string(AF_INET, str, u) >= 0);
         return u;
 }
@@ -82,7 +82,7 @@ static bool test_v4(FirewallContext *ctx) {
                 if (ignore)
                         return false;
         }
-        assert(r >= 0);
+        assert_se(r >= 0);
 
         assert_se(fw_add_masquerade(&ctx, true, AF_INET, parse_addr("10.0.2.0", &u), 28) >= 0);
         assert_se(fw_add_masquerade(&ctx, false, AF_INET, parse_addr("10.0.2.0", &u), 28) >= 0);
index f7bc8a7b2b3e6b6e75db74ab1b542acbc656f0b1..45a475539950d49553124cd110b3d7af9e37f8a0 100644 (file)
@@ -486,7 +486,7 @@ static void test_hashmap_foreach_key(void) {
                 hashmap_put(m, key, (void*) (const char*) "my dummy val");
 
         HASHMAP_FOREACH_KEY(s, key, m) {
-                assert(s);
+                assert_se(s);
                 if (!key_found[0] && streq(key, "key 1"))
                         key_found[0] = true;
                 else if (!key_found[1] && streq(key, "key 2"))
index a3767b47be72b64c135792eee6f2584442b9dec8..b7188d84fc038007a9d87aeb27c7cc63c060446c 100644 (file)
@@ -85,7 +85,7 @@ static void test_unhexmem_one(const char *s, size_t l, int retval) {
                         l = strlen(s);
 
                 assert_se(hex = hexmem(mem, len));
-                answer = strndupa(strempty(s), l);
+                answer = strndupa_safe(strempty(s), l);
                 assert_se(streq(delete_chars(answer, WHITESPACE), hex));
         }
 }
@@ -191,7 +191,7 @@ static void test_unbase32hexmem_one(const char *hex, bool padding, int retval, c
         if (retval == 0) {
                 char *str;
 
-                str = strndupa(mem, len);
+                str = strndupa_safe(mem, len);
                 assert_se(streq(str, ans));
         }
 }
index 55996500f3b264a436d800f135f97917386aa85f..dcd61b295fe9fe834eba2d81cb7ffd721338ce4e 100644 (file)
@@ -15,7 +15,7 @@ static void test_read_etc_hostname(void) {
         int fd;
 
         fd = mkostemp_safe(path);
-        assert(fd > 0);
+        assert_se(fd > 0);
         close(fd);
 
         /* simple hostname */
index 6d62958d67f7875eaa0cbe77d89bf68ef214b4f9..2ac662262431bd76971aee462b268173922bce65 100644 (file)
@@ -53,45 +53,45 @@ static void test_hostname_cleanup(void) {
 
         log_info("/* %s */", __func__);
 
-        s = strdupa("foobar");
+        s = strdupa_safe("foobar");
         assert_se(streq(hostname_cleanup(s), "foobar"));
-        s = strdupa("foobar.com");
+        s = strdupa_safe("foobar.com");
         assert_se(streq(hostname_cleanup(s), "foobar.com"));
-        s = strdupa("foobar.com.");
+        s = strdupa_safe("foobar.com.");
         assert_se(streq(hostname_cleanup(s), "foobar.com"));
-        s = strdupa("foo-bar.-com-.");
+        s = strdupa_safe("foo-bar.-com-.");
         assert_se(streq(hostname_cleanup(s), "foo-bar.com"));
-        s = strdupa("foo-bar-.-com-.");
+        s = strdupa_safe("foo-bar-.-com-.");
         assert_se(streq(hostname_cleanup(s), "foo-bar--com"));
-        s = strdupa("--foo-bar.-com");
+        s = strdupa_safe("--foo-bar.-com");
         assert_se(streq(hostname_cleanup(s), "foo-bar.com"));
-        s = strdupa("fooBAR");
+        s = strdupa_safe("fooBAR");
         assert_se(streq(hostname_cleanup(s), "fooBAR"));
-        s = strdupa("fooBAR.com");
+        s = strdupa_safe("fooBAR.com");
         assert_se(streq(hostname_cleanup(s), "fooBAR.com"));
-        s = strdupa("fooBAR.");
+        s = strdupa_safe("fooBAR.");
         assert_se(streq(hostname_cleanup(s), "fooBAR"));
-        s = strdupa("fooBAR.com.");
+        s = strdupa_safe("fooBAR.com.");
         assert_se(streq(hostname_cleanup(s), "fooBAR.com"));
-        s = strdupa("fööbar");
+        s = strdupa_safe("fööbar");
         assert_se(streq(hostname_cleanup(s), "fbar"));
-        s = strdupa("");
+        s = strdupa_safe("");
         assert_se(isempty(hostname_cleanup(s)));
-        s = strdupa(".");
+        s = strdupa_safe(".");
         assert_se(isempty(hostname_cleanup(s)));
-        s = strdupa("..");
+        s = strdupa_safe("..");
         assert_se(isempty(hostname_cleanup(s)));
-        s = strdupa("foobar.");
+        s = strdupa_safe("foobar.");
         assert_se(streq(hostname_cleanup(s), "foobar"));
-        s = strdupa(".foobar");
+        s = strdupa_safe(".foobar");
         assert_se(streq(hostname_cleanup(s), "foobar"));
-        s = strdupa("foo..bar");
+        s = strdupa_safe("foo..bar");
         assert_se(streq(hostname_cleanup(s), "foo.bar"));
-        s = strdupa("foo.bar..");
+        s = strdupa_safe("foo.bar..");
         assert_se(streq(hostname_cleanup(s), "foo.bar"));
-        s = strdupa("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
+        s = strdupa_safe("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
         assert_se(streq(hostname_cleanup(s), "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"));
-        s = strdupa("xxxx........xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
+        s = strdupa_safe("xxxx........xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
         assert_se(streq(hostname_cleanup(s), "xxxx.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"));
 }
 
index 30494f7fa1fe443396a7a8fab234e2a9d226992b..ddba5e4dfffca8a5a87ad129aa59dd7ed2c0fc3b 100644 (file)
@@ -286,7 +286,7 @@ static void test_linked_units(const char *root) {
                 else
                         assert_not_reached();
         }
-        assert(!p && !q);
+        assert_se(!p && !q);
         unit_file_changes_free(changes, n_changes);
         changes = NULL; n_changes = 0;
 
@@ -307,7 +307,7 @@ static void test_linked_units(const char *root) {
                 else
                         assert_not_reached();
         }
-        assert(!p && !q);
+        assert_se(!p && !q);
         unit_file_changes_free(changes, n_changes);
         changes = NULL; n_changes = 0;
 
@@ -328,7 +328,7 @@ static void test_linked_units(const char *root) {
                 else
                         assert_not_reached();
         }
-        assert(!p && !q);
+        assert_se(!p && !q);
         unit_file_changes_free(changes, n_changes);
         changes = NULL; n_changes = 0;
 
@@ -681,7 +681,7 @@ static void test_revert(const char *root) {
         UnitFileChange *changes = NULL;
         size_t n_changes = 0;
 
-        assert(root);
+        assert_se(root);
 
         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "xx.service", NULL) == -ENOENT);
         assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "yy.service", NULL) == -ENOENT);
@@ -1103,13 +1103,13 @@ static void verify_one(
                        i->name, alias, r, expected,
                        alias2 ? " [" : "", strempty(alias2),
                        alias2 ? "]" : "");
-        assert(r == expected);
+        assert_se(r == expected);
 
         /* This is test for "instance propagation". This propagation matters mostly for WantedBy= and
          * RequiredBy= settings, and less so for Alias=. The only case where it should happen is when we have
          * an Alias=alias@.service an instantiated template template@instance. In that case the instance name
          * should be propagated into the alias as alias@instance. */
-        assert(streq_ptr(alias2, updated_name));
+        assert_se(streq_ptr(alias2, updated_name));
 }
 
 static void test_verify_alias(void) {
index de8399dea8a1714d47f6ce66b969f4b5c58f91ae..cf438e6869fbfe34551b598d707009b90757e81f 100644 (file)
@@ -23,7 +23,7 @@ static void test_file(void) {
         log_info("RELATIVE_SOURCE_PATH: %s", RELATIVE_SOURCE_PATH);
         log_info("PROJECT_FILE: %s", PROJECT_FILE);
 
-        assert(startswith(__FILE__, RELATIVE_SOURCE_PATH "/"));
+        assert_se(startswith(__FILE__, RELATIVE_SOURCE_PATH "/"));
 }
 
 static void test_log_struct(void) {
index 428f3b952ae54fbfdb21cb4312e4cc02afc683ba..4acbbfb7afe64ae34871d74574bfcaec388a1981 100644 (file)
@@ -243,15 +243,15 @@ static void test_foreach_pointer(void) {
                 k++;
         }
 
-        assert(k == 3);
+        assert_se(k == 3);
 
         FOREACH_POINTER(i, &b) {
-                assert(k == 3);
-                assert(i == &b);
+                assert_se(k == 3);
+                assert_se(i == &b);
                 k = 4;
         }
 
-        assert(k == 4);
+        assert_se(k == 4);
 
         FOREACH_POINTER(i, NULL, &c, NULL, &b, NULL, &a, NULL) {
                 switch (k) {
@@ -292,7 +292,7 @@ static void test_foreach_pointer(void) {
                 k++;
         }
 
-        assert(k == 11);
+        assert_se(k == 11);
 }
 
 static void test_align_to(void) {
index 836460cec49bf44b967100d32c0ae6b0e81e01d5..314be9987926ecf220b20f6072f5103c0209c9e6 100644 (file)
@@ -8,7 +8,7 @@ static void test_normalize_recovery_key(const char *t, const char *expected) {
         _cleanup_free_ char *z = NULL;
         int r;
 
-        assert(t);
+        assert_se(t);
 
         r = normalize_recovery_key(t, &z);
         assert_se(expected ?
index da146aac2a0cb5ce45a7e5dabd7b679e99ca10a8..f0b716a4c5fd810c782062e1298f4aa967e69487 100644 (file)
@@ -60,7 +60,7 @@ static void test_user_and_global_paths(void) {
                         k++;
                 }
                 log_info("  %s", *p);
-                assert(u[k]); /* If NULL, we didn't find a matching entry */
+                assert_se(u[k]); /* If NULL, we didn't find a matching entry */
                 k++;
         }
         STRV_FOREACH(p, u + k)
index 0e8648aa6da0b82fe17dd67fee82275d8b921709..b6ebe7f5fc121ea981c5d772434ad2a1847994e3 100644 (file)
@@ -59,7 +59,7 @@ static void test_path(void) {
 static void test_path_simplify_one(const char *in, const char *out) {
         char *p;
 
-        p = strdupa(in);
+        p = strdupa_safe(in);
         path_simplify(p);
         log_debug("/* test_path_simplify(%s) â†’ %s (expected: %s) */", in, p, out);
         assert_se(streq(p, out));
index 857ecb59a460b1e865aed32b236ec822e3613863..d8d09118a6419034e25b6360aba50f18cecee283 100644 (file)
@@ -42,7 +42,7 @@ static void test_read_mem_pressure(void) {
         assert_se(LOADAVG_INT_SIDE(rp.avg300) == 1);
         assert_se(LOADAVG_DECIMAL_SIDE(rp.avg300) == 11);
         assert_se(rp.total == 58761459);
-        assert(read_resource_pressure(path, PRESSURE_TYPE_FULL, &rp) == 0);
+        assert_se(read_resource_pressure(path, PRESSURE_TYPE_FULL, &rp) == 0);
         assert_se(LOADAVG_INT_SIDE(rp.avg10) == 0);
         assert_se(LOADAVG_DECIMAL_SIDE(rp.avg10) == 23);
         assert_se(LOADAVG_INT_SIDE(rp.avg60) == 0);
@@ -62,7 +62,7 @@ static void test_read_mem_pressure(void) {
         assert_se(LOADAVG_INT_SIDE(rp.avg300) == 1);
         assert_se(LOADAVG_DECIMAL_SIDE(rp.avg300) == 11);
         assert_se(rp.total == 58761459);
-        assert(read_resource_pressure(path, PRESSURE_TYPE_FULL, &rp) == 0);
+        assert_se(read_resource_pressure(path, PRESSURE_TYPE_FULL, &rp) == 0);
         assert_se(LOADAVG_INT_SIDE(rp.avg10) == 0);
         assert_se(LOADAVG_DECIMAL_SIDE(rp.avg10) == 23);
         assert_se(LOADAVG_INT_SIDE(rp.avg60) == 0);
index 5872936a77c7455d4eab0e57e2c72833f63ddd02..2c2120b136fda51fb84a4d94e37e53213f22871b 100644 (file)
@@ -63,8 +63,8 @@ static int recurse_dir_callback(
 
         char ***l = userdata;
 
-        assert(path);
-        assert(de);
+        assert_se(path);
+        assert_se(de);
 
         switch (event) {
 
@@ -120,6 +120,7 @@ static int recurse_dir_callback(
 int main(int argc, char *argv[]) {
         _cleanup_strv_free_ char **list_recurse_dir = NULL;
         const char *p;
+        usec_t t1, t2, t3, t4;
         int r;
 
         log_show_color(true);
@@ -131,14 +132,20 @@ int main(int argc, char *argv[]) {
                 p = "/usr/share/man"; /* something hopefully reasonably stable while we run (and limited in size) */
 
         /* Enumerate the specified dirs in full, once via nftw(), and once via recurse_dir(), and ensure the results are identical */
+        t1 = now(CLOCK_MONOTONIC);
         r = recurse_dir_at(AT_FDCWD, p, 0, UINT_MAX, RECURSE_DIR_SORT|RECURSE_DIR_ENSURE_TYPE|RECURSE_DIR_SAME_MOUNT, recurse_dir_callback, &list_recurse_dir);
+        t2 = now(CLOCK_MONOTONIC);
         if (r == -ENOENT) {
                 log_warning_errno(r, "Couldn't open directory %s, ignoring: %m", p);
                 return EXIT_TEST_SKIP;
         }
         assert_se(r >= 0);
 
+        t3 = now(CLOCK_MONOTONIC);
         assert_se(nftw(p, nftw_cb, 64, FTW_PHYS|FTW_MOUNT) >= 0);
+        t4 = now(CLOCK_MONOTONIC);
+
+        log_info("recurse_dir(): %s â€“ nftw(): %s", FORMAT_TIMESPAN(t2 - t1, 1), FORMAT_TIMESPAN(t4 - t3, 1));
 
         strv_sort(list_recurse_dir);
         strv_sort(list_nftw);
index 7e1512a97dc6b0c6a313e5ad1c33108d45d1d94a..7ed6907cbd0af2d7fd2538bbfb4a3f8ccea04de2 100644 (file)
@@ -45,11 +45,11 @@ static void test_basic_enumerate(void) {
 
         for (;;) {
                 r = sd_hwdb_enumerate(hwdb, &key, &value);
-                assert(IN_SET(r, 0, 1));
+                assert_se(IN_SET(r, 0, 1));
                 if (r == 0)
                         break;
-                assert(key);
-                assert(value);
+                assert_se(key);
+                assert_se(value);
                 log_debug("A: \"%s\" â†’ \"%s\"", key, value);
                 len1 += strlen(key) + strlen(value);
         }
index fd12021cfa7e4fa8aa17eabe58bb08009c269ab5..e63137192cbc82b4d5aa27f04b4f8de43bf3b2f6 100644 (file)
@@ -143,7 +143,7 @@ static void test_set_copy(void) {
         copy = set_copy(s);
         assert_se(copy);
 
-        assert(set_equal(s, copy));
+        assert_se(set_equal(s, copy));
 
         set_free(s);
         set_free_free(copy);
index 058677590255bb02a2ddaa9abff7d73fd20626ea..1e08b7a0624efd9c98c221c757a9f5b319386c05 100644 (file)
@@ -16,7 +16,7 @@ static void test_rt_signals(void) {
         info(SIGRTMAX);
 
         /* We use signals SIGRTMIN+0 to SIGRTMIN+24 unconditionally */
-        assert(SIGRTMAX - SIGRTMIN >= 24);
+        assert_se(SIGRTMAX - SIGRTMIN >= 24);
 }
 
 static void test_signal_to_string_one(int val) {
index da484a40032d07a443d370f5caa47f75a0493ebe..c7d039af5500af82bb7e5c76200f80476fbbadb8 100644 (file)
@@ -16,7 +16,7 @@ static void test_socket_address_parse_one(const char *in, int ret, int family, c
                 r = socket_address_print(&a, &out);
                 if (r < 0)
                         log_error_errno(r, "Printing failed for \"%s\": %m", in);
-                assert(r >= 0);
+                assert_se(r >= 0);
                 assert_se(a.type == 0);
         }
 
index 584253c2fcb60c9a70b91c6774756ab815f81700..f9b22c7e11c47ba1c089658e56cbb3fc9c435e8c 100644 (file)
@@ -26,37 +26,37 @@ assert_cc(SUN_PATH_LEN == 108);
 static void test_ifname_valid(void) {
         log_info("/* %s */", __func__);
 
-        assert( ifname_valid("foo"));
-        assert( ifname_valid("eth0"));
-
-        assert(!ifname_valid("0"));
-        assert(!ifname_valid("99"));
-        assert( ifname_valid("a99"));
-        assert( ifname_valid("99a"));
-
-        assert(!ifname_valid(NULL));
-        assert(!ifname_valid(""));
-        assert(!ifname_valid(" "));
-        assert(!ifname_valid(" foo"));
-        assert(!ifname_valid("bar\n"));
-        assert(!ifname_valid("."));
-        assert(!ifname_valid(".."));
-        assert(ifname_valid("foo.bar"));
-        assert(!ifname_valid("x:y"));
-
-        assert( ifname_valid_full("xxxxxxxxxxxxxxx", 0));
-        assert(!ifname_valid_full("xxxxxxxxxxxxxxxx", 0));
-        assert( ifname_valid_full("xxxxxxxxxxxxxxxx", IFNAME_VALID_ALTERNATIVE));
-        assert( ifname_valid_full("xxxxxxxxxxxxxxxx", IFNAME_VALID_ALTERNATIVE));
-        assert(!ifname_valid_full("999", IFNAME_VALID_ALTERNATIVE));
-        assert( ifname_valid_full("999", IFNAME_VALID_ALTERNATIVE | IFNAME_VALID_NUMERIC));
-        assert(!ifname_valid_full("0", IFNAME_VALID_ALTERNATIVE | IFNAME_VALID_NUMERIC));
+        assert_se( ifname_valid("foo"));
+        assert_se( ifname_valid("eth0"));
+
+        assert_se(!ifname_valid("0"));
+        assert_se(!ifname_valid("99"));
+        assert_se( ifname_valid("a99"));
+        assert_se( ifname_valid("99a"));
+
+        assert_se(!ifname_valid(NULL));
+        assert_se(!ifname_valid(""));
+        assert_se(!ifname_valid(" "));
+        assert_se(!ifname_valid(" foo"));
+        assert_se(!ifname_valid("bar\n"));
+        assert_se(!ifname_valid("."));
+        assert_se(!ifname_valid(".."));
+        assert_se(ifname_valid("foo.bar"));
+        assert_se(!ifname_valid("x:y"));
+
+        assert_se( ifname_valid_full("xxxxxxxxxxxxxxx", 0));
+        assert_se(!ifname_valid_full("xxxxxxxxxxxxxxxx", 0));
+        assert_se( ifname_valid_full("xxxxxxxxxxxxxxxx", IFNAME_VALID_ALTERNATIVE));
+        assert_se( ifname_valid_full("xxxxxxxxxxxxxxxx", IFNAME_VALID_ALTERNATIVE));
+        assert_se(!ifname_valid_full("999", IFNAME_VALID_ALTERNATIVE));
+        assert_se( ifname_valid_full("999", IFNAME_VALID_ALTERNATIVE | IFNAME_VALID_NUMERIC));
+        assert_se(!ifname_valid_full("0", IFNAME_VALID_ALTERNATIVE | IFNAME_VALID_NUMERIC));
 }
 
 static void test_socket_print_unix_one(const char *in, size_t len_in, const char *expected) {
         _cleanup_free_ char *out = NULL, *c = NULL;
 
-        assert(len_in <= SUN_PATH_LEN);
+        assert_se(len_in <= SUN_PATH_LEN);
         SocketAddress a = { .sockaddr = { .un = { .sun_family = AF_UNIX } },
                             .size = offsetof(struct sockaddr_un, sun_path) + len_in,
                             .type = SOCK_STREAM,
@@ -194,7 +194,7 @@ static void test_getpeercred_getpeergroups(void) {
                         test_gid = getgid();
 
                         ngroups_max = sysconf(_SC_NGROUPS_MAX);
-                        assert(ngroups_max > 0);
+                        assert_se(ngroups_max > 0);
 
                         test_gids = newa(gid_t, ngroups_max);
 
index fa167fb263b57a9c24624c673c566bac42b3d42e..b27d26c81ace86d53b30e487e90441d620291433 100644 (file)
@@ -184,7 +184,7 @@ static void test_device_path_make_canonical_one(const char *path) {
         log_debug("> %s", path);
 
         if (stat(path, &st) < 0) {
-                assert(errno == ENOENT);
+                assert_se(errno == ENOENT);
                 log_notice("Path %s not found, skipping test", path);
                 return;
         }
index 9a9c974332d41141fa204cd52b12e03252996af5..8e2ccc06f46f9bb3507b32daa9d5d46440465065 100644 (file)
@@ -13,13 +13,13 @@ static void test_string_erase(void) {
         log_info("/* %s */", __func__);
 
         char *x;
-        x = strdupa("");
+        x = strdupa_safe("");
         assert_se(streq(string_erase(x), ""));
 
-        x = strdupa("1");
+        x = strdupa_safe("1");
         assert_se(streq(string_erase(x), ""));
 
-        x = strdupa("123456789");
+        x = strdupa_safe("123456789");
         assert_se(streq(string_erase(x), ""));
 
         assert_se(x[1] == '\0');
index 51ad45b5ac381e2932643016cd38367a35941f93..34f438cf9cc2aa462d8ae10ad77262a4966f87b8 100644 (file)
@@ -1007,7 +1007,7 @@ static void test_strv_fnmatch(void) {
         v = strv_new("xxx", "*\\*", "yyy");
         assert_se(!strv_fnmatch_full(v, "\\", 0, NULL));
         assert_se(strv_fnmatch_full(v, "\\", FNM_NOESCAPE, &pos));
-        assert(pos == 1);
+        assert_se(pos == 1);
 }
 
 int main(int argc, char *argv[]) {
index 7079bffa7fe4aa33a5606977040153290a852924..53f811450170d1347390cfe171a109cdcac3af6a 100644 (file)
@@ -656,7 +656,7 @@ int main(int argc, char *argv[]) {
         /* Ensure TIME_T_MAX works correctly */
         uintmax_t x = TIME_T_MAX;
         x++;
-        assert((time_t) x < 0);
+        assert_se((time_t) x < 0);
 
         return 0;
 }
index 9f2e6158674e2510612b5d4421b8f5dbe5165443..39d524e2b6b86d240fb4f8badbcf1cfcb748b60d 100644 (file)
@@ -14,7 +14,7 @@ static void test_tempfn_random_one(const char *p, const char *extra, const char
         r = tempfn_random(p, extra, &s);
         log_info_errno(r, "%s+%s â†’ %s vs. %s (%i/%m vs. %i/%s)", p, strna(extra), strna(s), strna(expect), r, ret, strerror_safe(ret));
 
-        assert(!s == !expect);
+        assert_se(!s == !expect);
         if (s) {
                 const char *suffix;
 
@@ -22,7 +22,7 @@ static void test_tempfn_random_one(const char *p, const char *extra, const char
                 assert_se(in_charset(suffix, HEXDIGITS));
                 assert_se(strlen(suffix) == 16);
         }
-        assert(ret == r);
+        assert_se(ret == r);
 }
 
 static void test_tempfn_random(void) {
@@ -59,14 +59,14 @@ static void test_tempfn_xxxxxx_one(const char *p, const char *extra, const char
         r = tempfn_xxxxxx(p, extra, &s);
         log_info_errno(r, "%s+%s â†’ %s vs. %s (%i/%m vs. %i/%s)", p, strna(extra), strna(s), strna(expect), r, ret, strerror_safe(ret));
 
-        assert(!s == !expect);
+        assert_se(!s == !expect);
         if (s) {
                 const char *suffix;
 
                 assert_se(suffix = startswith(s, expect));
                 assert_se(streq(suffix, "XXXXXX"));
         }
-        assert(ret == r);
+        assert_se(ret == r);
 }
 
 static void test_tempfn_xxxxxx(void) {
index 477ae03a0231fe8a62c432267c342a189d813a96..4fcd2e0efd0fbd7b0f0519d6717cddffc493af21 100644 (file)
@@ -65,7 +65,7 @@ static void test_unit_file_build_name_map(char **ids) {
                                              *id,
                                              &fragment,
                                              &names);
-                 assert(r == 0);
+                 assert_se(r == 0);
                  log_info("fragment: %s", fragment);
                  log_info("names:");
                  SET_FOREACH(name, names)
index 58a0d9dfd4de1162915540f10240da0295200d96..9bd634fcbd172acce305fc6b6be4939387cd76d9 100644 (file)
@@ -17,7 +17,7 @@ static void test_deserialize_exec_command_one(Manager *m, const char *key, const
 
         r = service_deserialize_exec_command(u, key, line);
         log_debug("[%s] â†’ %d (expected: %d)", line, r, expected);
-        assert(r == expected);
+        assert_se(r == expected);
 
         /* Note that the command doesn't match any command in the empty list of commands in 's', so it is
          * always rejected with "Current command vanished from the unit file", and we don't leak anything. */
index 94ca3f04bae7f872b8dfe0dc90b7123c156c4f27..af9537a3abcee9b047bc27b25fbea8303f5f0080 100644 (file)
@@ -374,14 +374,14 @@ static void test_make_salt(void) {
         assert_se(make_salt(&t) == 0);
         log_info("got %s", t);
 
-        assert(!streq(s, t));
+        assert_se(!streq(s, t));
 }
 
 static void test_in_gid(void) {
-        assert(in_gid(getgid()) >= 0);
-        assert(in_gid(getegid()) >= 0);
-        assert(in_gid(GID_INVALID) < 0);
-        assert(in_gid(TTY_GID) == 0); /* The TTY gid is for owning ttys, it would be really really weird if we were in it. */
+        assert_se(in_gid(getgid()) >= 0);
+        assert_se(in_gid(getegid()) >= 0);
+        assert_se(in_gid(GID_INVALID) < 0);
+        assert_se(in_gid(TTY_GID) == 0); /* The TTY gid is for owning ttys, it would be really really weird if we were in it. */
 }
 
 static void test_gid_lists_ops(void) {
index 9a5fbc6c8e280f8ba449f019660c059de6f933d8..a2708ecd086c7dbcc462c05989fbacc5f61013f7 100644 (file)
@@ -72,8 +72,8 @@ static int reply(Varlink *link, JsonVariant *parameters, const char *error_id, V
 static int on_connect(VarlinkServer *s, Varlink *link, void *userdata) {
         uid_t uid = UID_INVALID;
 
-        assert(s);
-        assert(link);
+        assert_se(s);
+        assert_se(link);
 
         assert_se(varlink_get_peer_uid(link, &uid) >= 0);
         assert_se(getuid() == uid);
index 6a4bbdbb480c60aab2bf499e65a8449540c6264d..d9767ba56493c2d585bbda58da69d72536ecc1f8 100644 (file)
@@ -77,7 +77,7 @@ static int print_status_info(const StatusInfo *i) {
         /* Save the old $TZ */
         tz = getenv("TZ");
         if (tz)
-                old_tz = strdupa(tz);
+                old_tz = strdupa_safe(tz);
 
         /* Set the new $TZ */
         tz_colon = strjoina(":", isempty(i->timezone) ? "UTC" : i->timezone);
index e509c63961ea13ec70fccfd014440ba24b3c9b30..5978e69b864decd3c5f365b645793b81562633e7 100644 (file)
@@ -47,8 +47,8 @@ static int parse_argv(int argc, char *argv[]) {
 
         int c;
 
-        assert(argc >= 0);
-        assert(argv);
+        assert_se(argc >= 0);
+        assert_se(argv);
 
         while ((c = getopt_long(argc, argv, "r:", options, NULL)) >= 0)
                 switch(c) {
index 4c0ec2eccb97c51974d3bb4d73d1e69c472f4d19..14b893ae8f88010df57064cf68912f9e7dbac92e 100644 (file)
@@ -183,7 +183,7 @@ static void dmi_memory_device_string(
                 const struct dmi_header *h, uint8_t s) {
         char *str;
 
-        str = strdupa(dmi_string(h, s));
+        str = strdupa_safe(dmi_string(h, s));
         str = strstrip(str);
         if (!isempty(str))
                 printf("MEMORY_DEVICE_%u_%s=%s\n", slot_num, attr_suffix, str);
index 489f5ad16a6cdb95a1a879cf2a6b0c36af56849c..bde2811dd75bb6f8ca38f0977c09fe4b1aa89f85 100644 (file)
@@ -237,7 +237,7 @@ static int scsi_dump(struct scsi_id_device *dev_scsi, struct sg_io_hdr *io) {
                  */
                 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL),
                                        "%s: called with no error",
-                                       __FUNCTION__);
+                                       __func__);
 
         log_debug("%s: sg_io failed status 0x%x 0x%x 0x%x 0x%x",
                   dev_scsi->kernel, io->driver_status, io->host_status, io->msg_status, io->status);
@@ -255,7 +255,7 @@ static int scsi_dump_v4(struct scsi_id_device *dev_scsi, struct sg_io_v4 *io) {
                  */
                 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL),
                                        "%s: called with no error",
-                                       __FUNCTION__);
+                                       __func__);
 
         log_debug("%s: sg_io failed status 0x%x 0x%x 0x%x",
                   dev_scsi->kernel, io->driver_status, io->transport_status, io->device_status);
index de1f8dbaa1171107c7a6076a34f511e359cb1c56..b46a1e5af6342faffe055928b3d0c08183325468 100644 (file)
@@ -337,7 +337,7 @@ static sd_device *handle_scsi_default(sd_device *parent, char **path) {
         if (!pos)
                 return NULL;
 
-        base = strndupa(base, pos - base);
+        base = strndupa_safe(base, pos - base);
         dir = opendir(base);
         if (!dir)
                 return NULL;
index 145204b226cb553325075e51fc4bd12316ec76bb..0d98b0788747245932131a32c305a99d6cb5a720 100644 (file)
@@ -223,7 +223,7 @@ static int safe_atou_optional_plus(const char *s, unsigned *ret) {
 
         p = endswith(s, "+");
         if (p)
-                s = strndupa(s, p - s);
+                s = strndupa_safe(s, p - s);
 
         r = safe_atou(s, ret);
         if (r < 0)
index af494d3075b2ad9ad6ec907fd040a3edc772d15f..33c8caa42ff410bdb57cf9a50cd414447cbcdc63 100644 (file)
@@ -512,7 +512,7 @@ static int display_services(int argc, char *argv[], void *userdata) {
                 if (fd < 0)
                         return log_error_errno(r, "Failed to allocate AF_UNIX/SOCK_STREAM socket: %m");
 
-                if (connect(fd, &sockaddr.un, sockaddr_len) < 0) {
+                if (connect(fd, &sockaddr.sa, sockaddr_len) < 0) {
                         no = strjoin("No (", errno_to_name(errno), ")");
                         if (!no)
                                 return log_oom();
index 1c68d283646412be33cb70cc654bb828f337fb18..13181b86ed82ee12c1eaddff68a0703fcfd64842 100644 (file)
@@ -100,7 +100,7 @@ static int create_device(void) {
 
         fprintf(f,
                 "[Unit]\n"
-                "Description=Integrity Protection Setup for %%I\n"
+                "Description=Verity Protection Setup for %%I\n"
                 "Documentation=man:systemd-veritysetup-generator(8) man:systemd-veritysetup@.service(8)\n"
                 "SourcePath=/proc/cmdline\n"
                 "DefaultDependencies=no\n"
index e58bae45d2293958c5bd4c7dcf6893dd02124b78..61973bf37a9fa6384a28a6296a54de7a90c58c66 100644 (file)
@@ -30,7 +30,7 @@ static int help(void) {
 
         printf("%s attach VOLUME DATADEVICE HASHDEVICE ROOTHASH [OPTIONS]\n"
                "%s detach VOLUME\n\n"
-               "Attach or detach an integrity protected block device.\n"
+               "Attach or detach a verity protected block device.\n"
                "\nSee the %s for details.\n",
                program_invocation_short_name,
                program_invocation_short_name,
index 9b90a1c2bc39c18587c3b15b10d7036b0887d04a..9f65d4ca4fd18c80e464e2eafd393d737e8a5616 100644 (file)
@@ -1,3 +1,5 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
+
 all setup run clean clean-again:
        @TEST_BASE_DIR=../ ./test.sh --$@
 
index d42c0df9a02948f90171779d57d030d961b5772f..a790cd78ac0fe3a96ce8e6f2b7a03f2ca3e74c8a 100755 (executable)
@@ -1,4 +1,5 @@
 #!/usr/bin/env bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
 set -e
 
 TEST_DESCRIPTION="Basic systemd setup"
index 440d7b8b297bfb69c94b3b11ce8a1dc8f008f402..571abe41c339dd6e1ff5ab7c60814e82a34df1ac 100755 (executable)
@@ -1,4 +1,5 @@
 #!/usr/bin/env bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
 set -e
 
 TEST_DESCRIPTION="Run unit tests under containers"
index 4ffa1bd6f4f9f02424a1665ac90f52be69c72e95..f827f90865b6978a81ba687e0aa45855082fb7f2 100755 (executable)
@@ -1,4 +1,5 @@
 #!/usr/bin/env bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
 set -e
 
 TEST_DESCRIPTION="Job-related tests"
index 3d7dff976bcaadfd9233c58cab41c6d4e02eb27c..0a3bfb545c14f53c14a3299f264f4e45f6d9a7dd 100755 (executable)
@@ -1,4 +1,5 @@
 #!/usr/bin/env bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
 set -e
 
 TEST_DESCRIPTION="Journal-related tests"
index 12b4530dd4504d2ccbe097b7cc1e70d88a282b74..10e2a56fad67bad7538c80f40482d8c43b9a3762 100755 (executable)
@@ -1,4 +1,5 @@
 #!/usr/bin/env bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
 set -e
 
 TEST_DESCRIPTION="Resource limits-related tests"
index 249c6792cf3e9eb59912ff4f6ce98275b6359e28..2aa442ce772237092e5ca7d20c20da2387d715cb 100644 (file)
@@ -1 +1,2 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 /usr/lib/systemd/tests/testdata/testsuite-06\.units(/.*)?   system_u:object_r:systemd_unit_file_t:s0
index 25c91adce92b7c7cf8c2c6de00dadfe28ab76978..1e74e1d7499abb413c227890618067f1921a6429 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 template(`systemd_test_base_template', `
        gen_require(`
                attribute systemd_test_domain_type;
index ff01c09b5ed82d1f970da3c15f7cd47bb17058df..43dbf3e8f44e307907aff766f2517190acea3451 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 policy_module(systemd_test, 0.0.1)
 
 # declarations
index d65d273055f6785e601731ddc1b6ad5fcae91cca..a867dea4b772f1e18ce2defd8153500b9e77b808 100755 (executable)
@@ -1,4 +1,5 @@
 #!/usr/bin/env bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
 set -e
 
 TEST_DESCRIPTION="SELinux tests"
index d195dcf184a25c640ab16f2855044b1bae3fce0d..5bc41386b56b29a8cbcfeec09dea2b755c42660d 100755 (executable)
@@ -1,4 +1,5 @@
 #!/usr/bin/env bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
 set -e
 
 TEST_DESCRIPTION="https://github.com/systemd/systemd/issues/1981"
index 76927be429108e64bdafb5c6b5500ffc39b04546..8fc5f1c9074684b5b0d41faa9b1a82327690d1c1 100755 (executable)
@@ -1,4 +1,5 @@
 #!/usr/bin/env bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
 set -e
 
 TEST_DESCRIPTION="https://github.com/systemd/systemd/issues/2730"
index 3c92efbcc2b81a8a11d3d94bddd504a6b3ac57a3..1c995f4801c8ae30770b1bac4abfdf5b85ace762 100755 (executable)
@@ -1,4 +1,5 @@
 #!/usr/bin/env bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
 set -e
 
 TEST_DESCRIPTION="https://github.com/systemd/systemd/issues/2691"
index 2a16ff3baabb52a967b6e9eb1a5a6c23fe775013..b510627a70e5dda9ce8210040d3f1bebf728a6da 100755 (executable)
@@ -1,4 +1,5 @@
 #!/usr/bin/env bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
 set -e
 
 TEST_DESCRIPTION="https://github.com/systemd/systemd/issues/2467"
index ba751853f9f313fe01bc1faab2347a5a667d768c..9adccc10b2e930f58138bba40a396bd3de110ce0 100755 (executable)
@@ -1,4 +1,5 @@
 #!/usr/bin/env bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
 set -e
 
 TEST_DESCRIPTION="https://github.com/systemd/systemd/issues/3166"
index 6e250b76690c57ed4108c9cc0a939ebd0d6aa7d1..977e04ee3f37f975be5133fc37bcf2a215b1d561 100755 (executable)
@@ -1,4 +1,5 @@
 #!/usr/bin/env bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
 set -e
 
 TEST_DESCRIPTION="https://github.com/systemd/systemd/issues/3171"
index a708465bdd51c65db19a0e4bc696f07ac7376aab..3d1e50447c734eb9b18da1e201d09704490aa089 100755 (executable)
@@ -1,4 +1,5 @@
 #!/usr/bin/env bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
 set -e
 
 TEST_DESCRIPTION="systemd-nspawn smoke test"
index 14d30ec1e11f044e2d76ac39a4bf03977ae0bfcd..afaa4cfbc6e00c58922b62291e745a3cb55af70b 100755 (executable)
@@ -1,4 +1,5 @@
 #!/usr/bin/env bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
 set -e
 
 TEST_DESCRIPTION="/etc/machine-id testing"
index f4422d4c7f313e3356d732174c06b4a5e0ae1ec2..d416c482d67cfc80bb962ef74863d02bf25a4ea8 100755 (executable)
@@ -1,4 +1,5 @@
 #!/usr/bin/env bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
 set -e
 
 TEST_DESCRIPTION="Dropin tests"
index dd43902967fd2e27df0927d5772786a32773f406..fd1b072c636b59fe85945a71c23c17ad32de9c45 100755 (executable)
@@ -1,4 +1,5 @@
 #!/usr/bin/env bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
 set -e
 
 TEST_DESCRIPTION="EXTEND_TIMEOUT_USEC=usec start/runtime/stop tests"
index f2c5f3c98312c3210d01be7f24060ebc9af2a129..079ecfd62947cfbf8cf38a9132c6e3357dcd9862 100755 (executable)
@@ -1,4 +1,5 @@
 #!/usr/bin/env bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
 set -e
 
 TEST_DESCRIPTION="UDEV"
index 2e7ed0c2d65321c98bd27b30991198ace4818118..a72365d0ec86edfc4d87313b3315e1f061f2ecf7 100755 (executable)
@@ -1,4 +1,5 @@
 #!/usr/bin/env bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
 set -e
 
 TEST_DESCRIPTION="FailureAction= operation"
index 165b31f7877572022e170768a2734e84db705010..5623708312a83355e8e888240faa28d415c18503 100755 (executable)
@@ -1,4 +1,5 @@
 #!/usr/bin/env bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
 set -e
 
 TEST_DESCRIPTION="test cgroup delegation in the unified hierarchy"
index bb9ddcde228d567b478f6356e1d63dff14837730..b663201efb023c31d2f54380e4b349ab27207bfb 100755 (executable)
@@ -1,4 +1,5 @@
 #!/usr/bin/env bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
 set -e
 
 TEST_DESCRIPTION="test changing main PID"
index c8b71e75a9b4df6af0e914a1a4441d1ae3ba6384..46dd990f799da875b5680ce6cacbca092d88b899 100755 (executable)
@@ -1,4 +1,5 @@
 #!/usr/bin/env bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
 set -e
 
 TEST_DESCRIPTION="Tmpfiles related tests"
index fb77dc7ab3283576dd95a48a88733e16aa10dd90..7268cde8371e53bbe9ad99a3c33200f66899e5d4 100755 (executable)
@@ -1,4 +1,5 @@
 #!/usr/bin/env bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
 set -e
 
 TEST_DESCRIPTION="test Type=exec"
index 2c13126a436db54c5ee16019d8275b1f94866c67..2dd0d4ca7f0c184664f14695428525e7b9b935c3 100755 (executable)
@@ -1,4 +1,5 @@
 #!/usr/bin/env bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
 set -e
 
 TEST_DESCRIPTION="cryptsetup systemd setup"
index 6fff9e51083b534ed658d80e1d2e4f96b23dc1b8..c382b3a11b484484ab37dfe53a896758c26b5788 100755 (executable)
@@ -1,4 +1,5 @@
 #!/usr/bin/env bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
 set -e
 
 TEST_DESCRIPTION="test importd"
index fe4c517895cb811710f471d198c8ed0b76e615d0..b38e37bfcef1087616f4e52a5e72f07ed7a80687 100755 (executable)
@@ -1,4 +1,5 @@
 #!/usr/bin/env bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
 set -e
 
 TEST_DESCRIPTION="test setenv"
index 144b88fa309c485235c9ece17785310725c40875..15229ba0183d39fa8a64316c26a03b289a198cab 100755 (executable)
@@ -1,4 +1,5 @@
 #!/usr/bin/env bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
 set -e
 
 TEST_DESCRIPTION="test StandardOutput=file:"
index d535c416845e7774661259d65c7b85a0ad506d4e..ae935fa7895408ab786af542911efee0cb256d20 100755 (executable)
@@ -1,4 +1,5 @@
 #!/usr/bin/env bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
 set -e
 
 TEST_DESCRIPTION="Ensure %j Wants directives work"
index 579e04dbf5071e41a4236366acdc1f6c4deccb75..a345e29314e109b5d77f89d1d9f10555dfa9bb7f 100755 (executable)
@@ -1,4 +1,5 @@
 #!/usr/bin/env bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
 # -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*-
 # ex: ts=8 sw=4 sts=4 et filetype=sh
 set -e
index aefe4bb00d74140e492a3b1902da35c11b9f8ea2..69dbdb2b5f0ff0beb475979c3b8ddaa0472c3546 100755 (executable)
@@ -1,4 +1,5 @@
 #!/usr/bin/env bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
 set -e
 
 TEST_DESCRIPTION="test OnClockChange= + OnTimezoneChange="
index 809f7fdca786581c9023b4834a2d0eee17f9b811..01dd8744a77cdb68eec7e35302978897232749e8 100755 (executable)
@@ -1,4 +1,5 @@
 #!/usr/bin/env bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
 set -e
 
 TEST_DESCRIPTION="plugged -> dead -> plugged issue #11997"
index 299bfe443af87c2ca8ca9b45711d95ea83d19ca9..78c4e6488b84eab49641bd1646f24a9bdc78e85a 100755 (executable)
@@ -1,4 +1,5 @@
 #!/usr/bin/env bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
 set -e
 
 TEST_DESCRIPTION="test OOM killer logic"
index d49a85828cc0c124e2f2b7c8ffb9c88087bfc6c9..dae72d98ef609ab5837f1b85b853495ec656a188 100755 (executable)
@@ -1,4 +1,5 @@
 #!/usr/bin/env bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
 # -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*-
 # ex: ts=8 sw=4 sts=4 et filetype=sh
 set -e
index 4d5ca336f15a72414c3d34c60f3b4fa8bc7f4739..5acc57363e5f3f47bfc5fddd52bfe147737996ff 100755 (executable)
@@ -1,4 +1,5 @@
 #!/usr/bin/env bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
 set -e
 
 TEST_DESCRIPTION="test migrating state directory from DynamicUser=1 to DynamicUser=0 and back"
index fddd5b672750e36b2d5d845e7f70647338c353c0..0eaaee960882beef19d9a3455609ebc1702a056e 100755 (executable)
@@ -1,4 +1,5 @@
 #!/usr/bin/env bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
 set -e
 
 TEST_DESCRIPTION="test NUMAPolicy= and NUMAMask= options"
index ebe4c4f1b5172b3a20a47934f1fc6d7e6af9700a..2f65908515c9a0ab836bcd4874aee465a05cc184 100755 (executable)
@@ -1,4 +1,5 @@
 #!/usr/bin/env bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
 # -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*-
 # ex: ts=8 sw=4 sts=4 et filetype=sh
 set -e
index dab05022bebfd64b4ee662ad7eb69213f8c814da..da7bfc64f359bcadb08504ada7a5c88d7dd4dd3e 100755 (executable)
@@ -1,4 +1,5 @@
-#!/bin/bash
+#!/usr/bin/env bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
 set -e
 
 TEST_DESCRIPTION="test unit freezing and thawing via DBus and systemctl"
index 653aee13ab5578bc4736d7e50d6ac2c1a0bc5934..c7565c6488f7d1e5cf05bc43fbe15841e6906e25 100755 (executable)
@@ -1,4 +1,5 @@
 #!/usr/bin/env bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
 set -e
 
 TEST_DESCRIPTION="Test ExecReload= (PR #13098)"
index bbbbad70647416a36720557a49d361c4ec63d841..6101f2ccf5164e962ceb3e59d51aac26d96aee7f 100755 (executable)
@@ -1,4 +1,5 @@
 #!/usr/bin/env bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
 set -e
 
 TEST_DESCRIPTION="test ExecXYZEx= service unit dbus hookups"
index aced44314bd637576c543a889d03beca09cc80d5..2e1879a7cbdf6a1d2cf9a641db95a4934926a10c 100755 (executable)
@@ -1,4 +1,5 @@
 #!/usr/bin/env bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
 set -e
 
 TEST_DESCRIPTION="Test oneshot unit restart on failure"
index 59f8868af27f43d40781df64ebb551e3fe3a7085..9d75bac2b68e9fd9c99350d78a80c12a6787bd54 100755 (executable)
@@ -1,4 +1,5 @@
 #!/usr/bin/env bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
 set -e
 
 TEST_DESCRIPTION="test that ExecStopPost= is always run"
index 9a7aa401bfa005ccaa52df630f44b21799a4f1e1..bb8bc1869708512c7370b7883a8b9ea3c3e054fc 100755 (executable)
@@ -1,4 +1,5 @@
 #!/usr/bin/env bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
 set -e
 
 TEST_DESCRIPTION="Test PrivateUsers=yes on user manager"
index 3caa76cecfbf15898a72dac731212aa9c594b589..320c6ffd039264a7f89db501535ca91b1d5db887 100755 (executable)
@@ -1,4 +1,5 @@
 #!/usr/bin/env bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
 set -e
 
 TEST_DESCRIPTION="test log namespaces"
index dea7e43876db1c1198d16b83d891f4813a3f68d8..7725995195734e9c05778bbe4433c73a67be3f72 100755 (executable)
@@ -1,4 +1,5 @@
 #!/usr/bin/env bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
 set -e
 
 TEST_DESCRIPTION="testing homed"
index c275770d4b745b99d09ee900fb4f60bd4ceb546b..8bdbe14b97ae43a198594907618ba989b2b073f6 100755 (executable)
@@ -1,4 +1,5 @@
 #!/usr/bin/env bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
 set -e
 
 TEST_DESCRIPTION="Test that KillMode=mixed does not leave left over processes with ExecStopPost="
index d1abc8aeebf552291279ab3a32afa55300e10985..0bece7d5b530f4c102718293f822f2e5c4821dac 100755 (executable)
@@ -1,4 +1,5 @@
 #!/usr/bin/env bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
 # -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*-
 # ex: ts=8 sw=4 sts=4 et filetype=sh
 set -e
index 297b22d4eea0373b5a561b5667d0e538e29d900b..c9f33457b32231af7940014e32a0a4dd9ddd0f38 100755 (executable)
@@ -1,4 +1,5 @@
 #!/usr/bin/env bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
 set -e
 
 TEST_DESCRIPTION="test adding new BindPaths while unit is already running"
index d8ac512a026539be4dee58456f7f6dca2112a350..97873799928d271eac767472681f1fd3d5e9d76f 100755 (executable)
@@ -1,4 +1,5 @@
 #!/usr/bin/env bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
 # -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*-
 # ex: ts=8 sw=4 sts=4 et filetype=sh
 set -e
index 5a0498e0667095f6c2a46653c61a0c02f0806bb0..7b306fa57b9b4b79bfb0b3d3977e07d2c37b704e 100755 (executable)
@@ -1,4 +1,5 @@
 #!/usr/bin/env bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
 set -e
 
 TEST_DESCRIPTION="Test ExecCondition= does not restart on abnormal or failure"
index 6b77693346d8176bd60d433d6f17cf2818636ff3..936e801c512f7cf36d7eb463e3cf009223962581 100755 (executable)
@@ -1,4 +1,5 @@
-#!/bin/bash
+#!/usr/bin/env bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
 set -e
 
 TEST_REQUIRE_INSTALL_TESTS=0
index 699b7b65d81b54dfd1f6bbb31be874e6c35517ea..7f44c66bffb37a95313b5b569e2d3da64c3e0831 100755 (executable)
@@ -1,4 +1,5 @@
 #!/usr/bin/env bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
 set -e
 
 TEST_DESCRIPTION="test timer units when initial clock is ahead"
index 28333d38d87622759a2a53ef6549a4d29d329b5d..3689be42032845678a00d5b09b6707fe3d7f7feb 100755 (executable)
@@ -1,4 +1,5 @@
 #!/usr/bin/env bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
 set -e
 
 TEST_DESCRIPTION="test credentials"
index 8e75651a22f8c401e1f1dc92c17e1d8c4e629eaa..4dc414294c94c8c9419197c13d454b3355d022a1 100755 (executable)
@@ -1,4 +1,5 @@
 #!/usr/bin/env bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
 set -e
 
 TEST_DESCRIPTION="systemd-oomd Memory Pressure Test"
index 34513f2ba228dffcfd918712ba43b8dce1d24e82..8181ac508fba1e54744dc8b1f7756d05d03e84e4 100755 (executable)
@@ -1,4 +1,5 @@
 #!/usr/bin/env bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
 set -e
 
 TEST_DESCRIPTION="test OnSuccess= + Uphold= + PropagatesStopTo= + BindsTo="
index df5ad3c0c611bac36520595d8973892b9c35b6ae..362236c0a83654f0c7195bb913a5aec38377b60b 100755 (executable)
@@ -1,4 +1,5 @@
 #!/usr/bin/env bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
 set -e
 
 TEST_DESCRIPTION="test systemd-repart"
index 343848e33a69da8bd9e4a337193d27a1d4f9ab6c..8821625bfff22f40fe12945b3e7bbcb8622fe1f6 100755 (executable)
@@ -1,4 +1,5 @@
 #!/usr/bin/env bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
 set -e
 
 TEST_DESCRIPTION="Test auto restart of exited services which are stuck in reloading state"
index e14bc83e09f0c4396462027308c4aea1a8320638..6cf4494395d0f2cf607e5c17eeb1ff1415e95bf5 100755 (executable)
@@ -1,4 +1,5 @@
 #!/usr/bin/env bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
 set -e
 
 TEST_DESCRIPTION="Test that mount/unmount storms can enter/exit rate limit state and will not leak units"
index 0f793bbee36f194da356c06cb6c0e6f4018754a1..45c5f71bfe37612c73bf06b9956b5089a11fce38 100755 (executable)
@@ -1,4 +1,5 @@
 #!/usr/bin/env bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
 set -e
 
 TEST_DESCRIPTION="Run unit tests under qemu"
index 85d5a53473ed97b65fedd1fe92ae13ffc1ac44be..db8290b73f75973bc9523a28ad5d56e7f8b9984d 100755 (executable)
@@ -1,4 +1,5 @@
 #!/usr/bin/env bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
 set -e
 
 TEST_DESCRIPTION="test RestrictNetworkInterfaces="
index c595a9f2de06df6ec76ac90bce1db64eff9d9b39..4d132ba9396d4223a3109c08d3cbd2d64753b033 100755 (executable)
@@ -1,4 +1,5 @@
 #!/usr/bin/env bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
 set -e
 
 TEST_DESCRIPTION="https://github.com/systemd/systemd/issues/17433"
index bd3f8250a3fa598b7f0bbe710d9d1e4ef01f71e0..227258f3e459869ae49934201ead6858ab4906b0 100755 (executable)
@@ -1,4 +1,5 @@
 #!/usr/bin/env bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
 # vi: ts=4 sw=4 tw=0 et:
 #
 # TODO:
index a64a7da258e31de8efa571276d205b29d6d0c361..3a9388d49ca31bf7832fe0623f05dd2e2ce7a48d 100755 (executable)
@@ -1,4 +1,5 @@
 #!/usr/bin/env bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
 set -e
 
 TEST_DESCRIPTION="test analyze"
diff --git a/test/TEST-66-DEVICE-ISOLATION/Makefile b/test/TEST-66-DEVICE-ISOLATION/Makefile
new file mode 120000 (symlink)
index 0000000..e9f93b1
--- /dev/null
@@ -0,0 +1 @@
+../TEST-01-BASIC/Makefile
\ No newline at end of file
diff --git a/test/TEST-66-DEVICE-ISOLATION/test.sh b/test/TEST-66-DEVICE-ISOLATION/test.sh
new file mode 100755 (executable)
index 0000000..28eed2c
--- /dev/null
@@ -0,0 +1,11 @@
+#!/usr/bin/env bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
+set -e
+
+TEST_DESCRIPTION="test device isolation"
+TEST_NO_NSPAWN=1
+
+# shellcheck source=test/test-functions
+. "${TEST_BASE_DIR:?}/test-functions"
+
+do_test "$@"
diff --git a/test/dmidecode-dumps/.gitattributes b/test/dmidecode-dumps/.gitattributes
new file mode 100644 (file)
index 0000000..a930f4f
--- /dev/null
@@ -0,0 +1 @@
+/*.bin binary generated
index 7b1b3e1835429033b5cc21b55cda097f6a4b174b..02dea65580ceafb98bfb7c06e1677612c446f5bc 100644 (file)
@@ -1 +1,8 @@
-/*/*       -whitespace
+/*/*                -whitespace
+/fuzz-bus-match/*   binary
+/fuzz-dhcp*/*       binary
+/fuzz-dns-packet/*  binary
+/fuzz-fido-id-desc/ binary
+/fuzz-lldp-rx/*     binary
+/fuzz-ndisc-rs/*    binary
+/*/*                generated
diff --git a/test/journal-data/.gitattributes b/test/journal-data/.gitattributes
new file mode 100644 (file)
index 0000000..483f6cd
--- /dev/null
@@ -0,0 +1,2 @@
+# Journal data in export format
+/*.txt  binary generated
index d2cadebde452e4d82fd4707032b3cfa113189df9..4960da56bea09e8f18e040d23a5e44a705114da7 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Test for AmbientCapabilities
 
index 545081d62923ac98a834f7691038ccfdd8339b8b..4c72b2eee5e934cc7717ef1b39a16d58ff5ea543 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Test for AmbientCapabilities
 
index 2e3fe59124fabb6f7c8618b36845289daafad320..13a5d4577e061fd3c69fea60de047b7d9187f7be 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Test for AmbientCapabilities (daemon)
 
index 9377ee16b2db22d1140f0bff0240cb39bcac470e..10cb44012ba288e2ed99c6874f558ac6bbc10c90 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Test for AmbientCapabilities
 
index 07a6c7511db3c05cf32dd9a0089a300b080cb22b..5400cac9516de38129ced1a7820430ebee93343e 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Test for AmbientCapabilities
 
index d91cc09a48532bf5fbc60ff95c94fb0136ecd03e..5336bec3d80c4086876653786d94a37fa917e90e 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Test for AmbientCapabilities (daemon)
 
index 60c5be6dc98c2ddce384b04d9db05597c76cb295..a54aca9dc39f5de25986568bf0ac0b9993000c8b 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Test for basic execution
 ConditionKernelVersion=">=3.0"
index edab18bb0fe7255710755dba623c999c9237bb43..bf6968f3c172587ab0370d6f115830030c39c658 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Test for BindPaths= and BindReadOnlyPaths=
 
index 4486f6c25d87725a0519c4de5d26b42b5e5d3f86..1b1217e094554eafbb5afe61dd08a9ba10792e30 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Test for CapabilityBoundingSet
 
index 5c7fcaf437242d5ab8901ede3de7e7076e44542a..1ed3ccbb25fd78f109f17610b77d9bea42f355ea 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Test for CapabilityBoundingSet
 
index d7d33202044e377a25d8ad8756b55c752f108f02..8eb142c64a480b00ec544141228ca04389eb6782 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Test for CapabilityBoundingSet
 
index bf1a7f575af9d02ccf5d4ebe5624d38b9f1fe6d4..be5a5e5b87f7b36fd6c73ee91c1dc38bf8524096 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Test for CapabilityBoundingSet
 
index 4a406dc17f468be9eca83a1760d1c8105bcbf656..342219cbeac24432d12eda36f3029773cf0a2b71 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Test for exec condition that fails the unit
 
index 9450e8442a2fa2181bc00f35dfb062b7f8487304..b69e16134754b5c2db430451d34a25517628279e 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Test for exec condition that triggers skipping
 
index 84d550a3855b80890d7a2c97c742306a26486cf8..2a8544acb1f403cc9353b404965facdbf44805e8 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Test for CPUAffinity (simple)
 
index 0dda77f939e18dfd1c25e4a9606d2eb2db5dfcce..bed48c822fcaf491700c1a4ceac219f082860c03 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Test for CPUAffinity (reset)
 
index 4a45d3b2d5ab72f810ad49b43cd4b35983367b04..774cd642cd8dfe3b9eb904b92fb3a3e11debf476 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Test for CPUAffinity (merge)
 
index 90040ee53310e3a5212222873c97b316f661c96b..daaed6c64c2b30f5e8044ea24f408b30883a5a0c 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Test DynamicUser with static User= whose uid and gid are different
 # On Fedora, user adm has uid==3 and gid==4.
index 1cc9518fc653309d36e5f7edcc1b18ad68460d96..db8b88efdb910269a398c83763d88f78d1efb89e 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Test DynamicUser with static User= whose uid and gid are different
 # On Ubuntu or Debian, user games has uid==5 and gid==60.
index bd7881d2865f798975c8c2f75963241aa21c396e..0c2a218be0d2a392e9d832643222dad91e8b785b 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Test DynamicUser with User= and SupplementaryGroups=
 
index f28078f2422138e85373160c991e156136489213..061bbd2b9395a8b82e24c56b592e87ee137cb87b 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Test DynamicUser with User=
 
index a3e566248dff92d0397aa0952bc8f46475764702..790279ab17ebcbf8319ecaa0c7eea4ab87b7a665 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Test for RuntimeDirectory with RuntimeDirectoryPreserve=yes and DynamicUser=yes
 
index d7af69907acd184d2414a0417fa8a13d28cce185..18df74e4471adca4ccfba0d1fb2efb2791b24d4c 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Test for RuntimeDirectory with RuntimeDirectoryPreserve=yes and DynamicUser=yes 2nd trial
 
index 1ea47ef6ea6c39161533f35e8ccb2abc3a982d9f..831a808f901871631f3f347c936af4bdfcf63afa 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Test for RuntimeDirectory with DynamicUser=yes migrated from RuntimeDirectoryPreserve=yes
 
index 5efc5483b8880caa8d2e2e725bcca6c728ae7dc7..1c79e4f72212e72d6748178d4219d51cea44b77f 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Test DynamicUser= migrate StateDirectory= (preparation)
 
index c72302ffd598fe149de72a6e9c79c33ef34628eb..015b74ce229b0daf72df839c80a1c0b0524b4271 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Test DynamicUser= migrate StateDirectory=
 
index 6103193ba37eabafaf95e8721a3f3f5972dec86f..2555142d7b3f1970a3561ac90758d6cd6d43f25b 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Test DynamicUser= with StateDirectory=
 
index e3549c22c9c48c58317f7ef1153d011c90a44002..fb0b57bc00b2a55ed8407e3baf7310d94514c70e 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Test DynamicUser with SupplementaryGroups=
 
index 9c92d4bc8113e882d83ae1b76b122314b876322f..6c3118643f257d6c5e3c42ac1ad25b132ae5e7b1 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Test for Environment
 
index b9bc225635a9a1697ebba4dc044e9a199cef324d..d9b8d22667f89c89c702aef0df4b5095893aa6ea 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Test for Environment
 
index 6a2e60ec24f99144362ebed9178ef3d7db613355..b5cb2a4445ab525f3539c3f748398572d5beeece 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Test for No Environment Variable Substitution
 
index 06e77af220000365837161950704efe28cc4a72e..5655be0a22a7594dd26b98a2bbf3795c5be2de8d 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Test for Environment
 
index 9bcb133aecce4b25901ed0a78947d599c4a42a98..4ad5a9bb3b8cf886750e4d7d8de9355c1ccd54ae 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Test for EnvironmentFile
 
index dd27de84a851714f75edd1e4e6158dd1d58342d8..5969cc6764df0703e6fc6bc399737c6517ea12a7 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Service]
 ExecStart=/bin/sh -x -c 'test "$$PATH" = "/usr" && test "$$VAR1" = word3 && test "$$VAR2" = "\\$$word 5 6"'
 Type=oneshot
index ba477fbdcdb816b108171a4332f9f8d6a3057e5f..b0fa6a36e49604e2dbd27a39692487750b64e3af 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Service]
 ExecStart=/bin/sh -x -c 'test "$$VAR1" = "word1 word2" && test "$$VAR2" = word3 && test "$$VAR3" = "\\$$word 5 6" && test "$$PATH" = "/tmp:/bin"'
 Type=oneshot
index 45877b1d127231982c45bce0352007391903b7b3..5f55a4b9346944bcbddd1dcc470e6c08b3e7b0ee 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Test for ExecSearchPath with EnvironmentFile where EnvironmentFile sets PATH
 
index 65a04e7dbe4feca2c9422a3d5375d5d38907629a..b8335bcf97c276c0be62f9de14c9530d4d595d02 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Test for ExecSearchPath with EnvironmentFile where EnvironmentFile does not set PATH
 
index 62c7742b10ab0fa779b1bc8a0e2c93bfcd140267..a1511616e2c86fb3ac8c517adcf5e00afe2e71a2 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Test for PassEnvironment with ExecSearchPath with PATH set by user
 
index 83eb0d680ad4184196e3c135d7868d266fa09955..d8a41c1ed790d971211865ccf984c376e8f21643 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Test for PassEnvironment with ExecSearchPath with PATH not set by user
 
index 740bab1d416b200ee76eef089f29d35e547fba3f..30d6b3280d8e601de9ae3c725d4d22259dfb7727 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Test for specifiers with exec search path
 
index 67b71709f36f0554d8de792b35c69e0f80c57a9a..150afe2fccc7dcc281846e9c1b40333861374d04 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Service]
 ExecStart=ls_temp
 Type=oneshot
index e02100a869fd0d8633cdd920b76d4e6c025fce82..a1e59c5d1157edf3b7042478365af7f171dd10d2 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Test for Group
 
index be7c7969127835ffab3854906d836fa0984b8211..58dce1e3d640b9061e81b4a40e3df21834699d0d 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Test for Group
 
index cf0773229e2d6240f53e6bf46749f094ce71f0a4..7f167298903a226dda57856eabf060bbbc05dfc5 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Test for Group
 
index be559923953a11a3f73ff82fdbe7dbe17620f2ac..9f21557d8260312ff71cf4f3edbbdf27b6e823ee 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Test for Group (daemon)
 
index 73addf5f05500bb0b6ed546bfe60d99fdb6e5ee7..e97248109d49124490c683ccd8ffb2af7eed792f 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Test for IgnoreSIGPIPE=no
 
index f81c01719e9ad74b790d5add5e1ae9fde90b5d24..ee3aa9a2b3eeddf2de842ebb3634f9ab252af967 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Test for IgnoreSIGPIPE=yes
 
index 430a6b78c2557e3f9e4462b5aad0154aaeaef1bc..520bc539b0a45f73cfc10ae8524922b225edfd5e 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Test to make sure that InaccessiblePaths= disconnect mount propagation
 
index 5ff6f3605b1e1acb0c938ac901e26d2f0fb02385..0d64aa19c833763428cbbd110870aafc29b8e92c 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Test to make sure that mount namespace setup works properly with the 'InaccessiblePaths=/proc' option
 
index 29bb8510b42cf9287f5e710874974a19e92b8214..3b946b785569d18cb1aae53f036ec5dc727ce928 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Test for IOSchedulingClass=best-effort
 
index 87dbed14c1a991024c1f71cd35ab738c77a05266..b1e64bbbc167db48b6b651aff0868cf256c67172 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Test for IOSchedulingClass=idle
 
index b6af122a1efe95e37e4e370c1f7b19d18076bf49..efe31822615ddc9996ecca92c5aaa5e068960f5a 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Test for IOSchedulingClass=none
 
index d920d5c687396ada38382e927bcd06d8c848c158..ef8e2eb7f1652c91df59e8080fe18bd177c8b014 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Test for IOSchedulingClass=realtime
 
index 0cf1f332e6bc27afc11bc219292f92f6f95827e8..3fec1b726fb5097395856859ecb1144543983b04 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Test for find_executable() with MountAPIVFS=no
 
index 45152a26f01daf7ea403a5f1f5ccda4f36f7cfec..5d954da6ace9cb9ad68ef9be14ca44a7002281b6 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Test for NoExecPaths=
 
index 2234c53c3ff36472e0d534299eaab92f629f7f73..25b5f1ffcc8221703d83f18b7d5fbf2f6e31d217 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Test for OOMScoreAdjust
 
index 456a8f80cf8b0a7cb5807389d2e077a18d0ba8ea..ea6c23f78e808dfab0c153b93f81a7b485f681e5 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Test for OOMScoreAdjust
 
index d257e48cda4d25203bcd1f4ac29ba2dcf6d7d335..6b19a12bb7e24617fc3e063d0c8fdb117420d649 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Test for PassEnvironment with variables absent from the execution environment
 
index 291259a34716c3be1e3575d4b5bfe9708fddc6f2..6ffc5e7de680ed045f2798fe4b66055150d59bf4 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Test for PassEnvironment and erasing the variable list
 
index e88699802f243ef82ba6abc7e9e906e3a76d28fa..b8e904fb6d28d722cdc4790282fa89a67a5da0f0 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Test for PassEnvironment with a variable name repeated
 
index 05c1bdfe882d88a8ae09fa154a6986f82a7db022..b69592ad6a9db12fee88c68642294f4c3c861150 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Test for PassEnvironment
 
index 8511174411af7d31281eb5e77ce240e4858711e8..0783a873640408166721138fc2822a67d12aaf54 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Test for Personality=aarch64
 
index ccc2c8d83de9be69b970b7d709e884b3cc8157f4..72f063a59c1556ac00ecceeab32be6527c5e53ff 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Test for Personality=ppc64
 
index 2a7625087df5fd9fa329c8a9406946fe1fdecb8a..5e38029c05433a5ca29dbfebb2ec9060e9e57b58 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Test for Personality=ppc64le
 
index 89f7de89d03b3fae82c12cbfacbeb1a1d1e1ee3e..439dc5fea87ac6a2e078dfe1207188384c13ff0f 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Test for Personality=s390
 
index 433e69a6d10d818a1f07ed3bf21c282218691a41..c6a0a4061c7a4a9ae198f76d6ad6a57480e863c6 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Test for Personality=x86-64
 
index 4ece7de718e794e6078283cd2e1fa73a5d3cf31d..8b820b31c6eee67e484a20fcdffccd1ae6441d02 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Test for Personality=x86
 
index 19b1da524005004e4bfd54ffa966a8a077db4ab6..021cadff529291d37f51ab0a87876770802ab4e3 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Test for PrivateDevices=yes with prefix
 
index 8f135be0b5e902e25da247d108ea96a532fcef22..a07e82284158a38b0ecf98ae03280eac48975526 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Test CAP_MKNOD capability for PrivateDevices=no
 
index 30ce5492546f0035f0af154e430eed8bec73ad0c..b0ce2d409c55bff2bd90b2f7f69ef3a404944352 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Test CAP_SYS_RAWIO capability for PrivateDevices=no
 
index 4ddbf189b7b1e4cb52e2689a4d21b799b2cbf2ee..31a5e3c72b23470f17ef62253c5ccb9c0e3262ce 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Test for PrivateDevices=no
 
index b98cfb5c7eaca13f6f059c77e6559f100763073c..f798f3167082573b3b7c54fc55268fd5d27e6ab1 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Test CAP_MKNOD capability for PrivateDevices=yes
 
index 5b0c0700f2c89d27b6bfb06f0657d548ae2e255c..d902c234e204032da651c99b11e11099de2d1fd3 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Test CAP_SYS_RAWIO capability for PrivateDevices=yes
 
index 70a7ed24f465d75d1c49cc686c393c88614e41a5..a39ae0f846899be85ca3d25bdcab1817922dda0c 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Test Group=group is applied after PrivateDevices=yes
 
index 35166672073cd3ff66f1f94c6974cebfe9725a3e..564e95892532c4304097f326a6eb22fae1cc23a6 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Test for PrivateDevices=yes
 
index 8f5cbadf0408aa7d37541289a4091c6693c44895..0fff048b94f704f1056742c8dee1c24d23f75e1b 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Test for PrivateNetwork
 
index 009e6bef95b5cb827a5d563ec2181af95eb5f690..f67afee101cc89d39103cd3f0fa4dc0a63c6b025 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Test for PrivateTmp=yes with prefix
 
index 59f60f47557b63a7cf08be9dd04fa05fb52ae65a..6a8a3fc319387d8eb70cbca08553808bfad029c6 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Test for PrivateTmp=no
 
index 907c291b81c9f0bebad0b59a3109b57d78a2a5e4..6395be0842d6bf6b651382e01939b9e0666ccd47 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Test for PrivateTmp=yes
 
index 1522ff80e163de2a4a9a2eeebb501c8a57ff65d1..f84e6b6f037ced650971ea57f51663773663feef 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Test ProtectHome=tmpfs vs ProtectSystem=strict
 # Test for #11276
index 36aae7caf1a4553c023d74254e015c8e278be21d..54789627555fd562142f94d203e28c9a13e99b81 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Test CAP_SYSLOG for ProtectKernelLogs=no
 
index 4a5f1a08e902480435800edcdbb4cfb932f7489a..6fe12410d96b06eae7617a31e14f9147644df393 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Test CAP_SYSLOG for ProtectKernelLogs=yes
 
index 1b73656305e4455f703fafcb265060f5ad2a9ab2..7236af2b245e226467d91243fe6f5a7da743c941 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Test CAP_SYS_MODULE ProtectKernelModules=no
 
index e43e72733c93c812d9a11b3493ba5a9a0902750e..e40160daf50d182d77035bb16667db13cf2fc178 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Test CAP_SYS_MODULE for ProtectKernelModules=yes
 
index 07758121cd3b56cf42ed2f15ab982def8873fd8a..0ecf1a2b6ce2000652415077b21aab2d2c5d9ed9 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Test to make sure that passing ProtectKernelModules=yes disconnect mount propagation
 
index 7edb0daa36e3f8ebca8f2cf2b5f5adefd3291dcc..abc180b3b38930ac5d4a6e225e48420e66057207 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Test to make sure that passing ReadOnlyPaths= disconnect mount propagation
 
index a9a715905cd1feffdadaa6eec97b6bccadf42d74..5587e8dce71eea767d94fea7cbbecee8bdc35e84 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Test for ReadOnlyPaths=
 
index 438c7de70471fc8fef487176f694fe5fe8b62998..71c7e7b92683eca29ce20040a91e996ad3286f96 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Test for ReadOnlyPaths=
 
index a0ca68f67da0d37a99767e418216a8fe50f61dc2..21814c2f26289fb0b89021bd6e11be66000754c8 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Test for ReadOnlyPaths=
 
index b38978df424acb16e395051089b0637c80d09143..35e736f74261cd261c1201cca790ebf3a4be04c2 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Test to make sure that passing ReadWritePaths= disconnect mount propagation
 
index de98cd0a2ed41b5ab9c33a669a30e550c806cfdb..1270b60e0ba4231a5c19e6172607e5cdc97e006b 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Test merging RestrictNamespaces= with all flags
 
index 6702e6aab2e859f754172936ea45a72f5cf0ea14..fdeb3f140d131abf0f6ac575befe5a892e042423 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Test merging RestrictNamespaces= with AND
 
index a52455204dc3f12c9a27e4259380c4200d8f9ce0..fca3718c9d703996f4ad90a7bae30b220c2109d3 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Test merging RestrictNamespaces= with OR
 
index 7756a2575e5b186ebca76a0be5c4ab09c6eff216..b257afb2b59bb8233072936ef88148368f77c185 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Test RestrictNamespaces=~mnt
 
index 2c5b942601c972eb3dfe3fecd3707070c9af4b16..cb28c0c2e67f8e1f0f8281144131d8e7f619cc0d 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Test RestrictNamespaces=mnt
 
index 5ffe081e45b70e9a0f9cacbd8b5a90777cefd66d..035c8b5beea92890395cead4d061d2e8ada4a89e 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Test RestrictNamespaces=no
 
index 8e077ed3a0f8a7438cd343acf0f63f4c42a14fa0..f9436d29f7332726edcd61378c9218ee275c1451 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Test RestrictNamespaces=yes
 
index 85ae5161c4aab71a9f6e90f06048ba43a8ea288b..580bac94eacadb239b9cdf84fc704e58b7ad8172 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Test for RuntimeDirectoryMode
 
index 1e3b6b4151739f9c2163e17d8c8142ee0b941528..79bebc4616a81ad3385ff8e44a357b03057921b2 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Test for RuntimeDirectory owner (must not be the default group of the user if Group is set)
 
index 54782f9bbddb2e7c93eb179f01e1ba0dcfe27084..3b42a9fc419169120f01fb6d1849f2f7356019c6 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Test for RuntimeDirectory owner (must not be the default group of the user if Group is set)
 
index 663afe1188c7509fdb506561cb0dd4590a938310..804048ea0596234c7d9c8ef026c07df6a29f38fc 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Test for RuntimeDirectory owner (must not be the default group of the user if Group is set)
 
index 07dd7ca3afce8f8aadb30a99ac63659ce7985d6d..e2c0890b006530aa2f51f4876f30a60d1d8837f2 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Test for RuntimeDirectory owner (must not be the default group of the user if Group is set)
 
index a33044d23cbe26ab8871df7257f60aac49f58cd4..1928c57acefd0f9925e3bf08d063cc22657a8828 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Test for RuntimeDirectory
 
index f128e3c4b3e8cb111ec6fddab2e0cf194c0e6a75..4cb1b065187309d9006af58bf9a12f6918671680 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=https://github.com/systemd/systemd/issues/2637
 
index a58abc68dd6057e355eb25f63b3648194de7c781..190ebe93e6e6b045fd47ecd35bdeac1217fecc41 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Test for specifiers
 
index faecbf37bc5965a89caabe47fce13acfb634ec0a..5e30efce4c54e6ad9d55a093cda4a72903a8929f 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Test for specifiers (template unit)
 
index 1ca536ffc562f40af02317f3bea264c066ba7fa9..83db6098c02e9a44c70ab576ff986d23eb32a1af 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Test for StandardInputText= and StandardInputData=
 
index a0c786c301984faf77648a12ea628b39f4d91bcf..b115a6d8d4ec6b3bc30d06947b9ef6eeb487ce12 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Test for StandardInput=file:
 
index 8fd11caf8e7678769179cffc6f1f97f7bc177834..618ae7dd1f8d4daeb6c4e51084c5b3af05fc970a 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Test for StandardInput=file:
 
index 2118bfc2a661c0f022f2489b007f9b23a740a7a1..45d29ecfdd6edd92fe175f84b6d67207dc800a34 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Test for StandardOutput=append:
 
index 8d484a456e6b4eec1901de9b9969b213d329d067..8b689a249430bbe8c96898baa23a119f0485b364 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Test for StandardOutput=file:
 
index 8d6ea2769fed3fa9e80db45a8fe04eb0a608fb9e..1a86d92d8b620094a33e7d9efd033472fb3319ce 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Test for StandardOutput=truncate:
 
index 2a7ce87bb4a6a9f2b479cbf32b3affd4353eed0b..362e539287cdb34fe12745e52445cc261b61e3c1 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Test for Supplementary Group with multiple groups without Group and User
 
index aae20fbf951cc0475fce3518c5e41c8cbd195849..ff3fdc814253b9d5af2dd7118c5393b351bed902 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Test for Supplementary Group with multiple groups and Group=1
 
index 2714235be6809b5ffce6d2b25675a7fc19a5d341..f35ff8476579a223fd83248d34b84d7873980a4f 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Test for Supplementary Group with multiple groups and Uid=1
 
index 405c5f9bfe78d9e68ee4b53af8c0bde9c6b7fac7..aae71d0a30934f0d48ae58f6d28946c0ecbf7e52 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Test for Supplementary Group with only one group and uid 1
 
index f9b721696bd690b2d2e3d71a01621e115a850bda..c870774382aea4ca1274f19171405bfa1ea7021e 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Test for Supplementary Group with only one group
 
index 6f6e2ba8226527b102bc90e4a40bffde2b8c117a..75601eab573787bcab29f25c4a6282b923959d52 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Test for Supplementary Group
 
index e167d2716ba888593412b9efe3125c83ae80b948..f2be6003c8fbe9a944ea4f26e4b012afb2082593 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Test for SystemCallErrorNumber
 
index 203215682fb7bff382a0ece6b578d43bd2eaac61..5d99a97476b7a5686d9b61bfa7c0b033e766395d 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Test for SystemCallErrorNumber
 
index c4b0799031999f647b67b1b6a85ec9e61a103971..3aad372900b3db5e07390c0623d42b5fbae74f9b 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Test for SystemCallFilter
 
index 452aaf8273e0dc6807e43a900ebf9a517297e254..8cdb8de45b8f91f13f6e5eafb4a075ad039351ed 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Test for SystemCallFilter
 
index b8c96704d23b73de2ff7abc19b450cc7be966fb2..98c88fd0b15ee70e9ac856a968dde061a8501e56 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Test for SystemCallFilter
 
index f3a752b3ef9f60ba1c37e7e6d38de50408ab7a22..c7eddea6655cf1690999f914cc3fe5beb0bbc182 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Test for SystemCallFilter
 
index 1df076ab90bc7c48a94b4db9844a1562aa1aba9e..96eaf16a45bc257c2c6f8c28e033ff0c9aa57941 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Test for SystemCallFilter
 
index 7d72f5ab83600468bb7a54e7b3f7da617a15bcb7..f8f409284457014619c580996901dbbbaf81c850 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Test for SystemCallFilter
 
index 3569b4500c68d7981b155320a050e2a2bdd8e589..de2c6ad2d6a4d415b0b4457eaf2d5739570ec4d5 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Test for SystemCallFilter with specific kill action overriding default errno action
 
index 04bfd6bfcbd5c0f2859008d8cd32acf4c8d4f9d9..ffa35e64dff2a847f2c18f6910541161d9f3d7e6 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Test for SystemCallFilter with specific errno action overriding default kill action
 
index b1195d0d253e8f971bb68e9b92653c4bfc89a36e..deba1543b44883394a9f81de3f06a75c4809408a 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Test for SystemCallFilter in system mode with User set
 
index da129a30e4dfda0587a96bfc76c19f58284291ed..43fb9c3395dfd97e9a90160c9e24daaa5fe95bc0 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Test for SystemCallFilter in system mode with User set
 
index 488a3bb79e5d9d9b842cb141aa605280fb88ac37..005c4ac1c82927abd39fdffbe78e52d448319503 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Test for SystemCallFilter in system mode with User set (daemon)
 
index 4b2636eb44d2f37a211bc235a921a9f238e9e3c4..c7a4c4a61435336997310d737b270ba28bd5c4fc 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Test for SystemCallFilter with errno name (for issue #18916)
 
index 951e7ac36b4f442a18c0ef4cb96673ea2ae6622a..267832366fd32895864b54afedc01924ea193c73 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Test for SystemCallFilter updating errno
 # test for issue #9939 which is fixed by a5404992cc7724ebf7572a0aa89d9fdb26ce0b62 (#9942)
index 8380d5a15516ba82cb8428a5670ed2488e94cf33..a9023314adbe262e85c55f5c3082e5f34c5e6b7a 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Test for SystemCallFilter with errno name
 
index dbb9540a1e9413d146627e690a9e08951f2f436c..ffbc84a3138beceb67abf0a8d5f31521d98fd80a 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Test for SystemCallFilter with errno number
 
index 371e5674b1c0957ab83f35ec624c2fe9cd312f94..1610c63a4adb1697fd48f734f1ec7a9e64d9e734 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Test for TemporaryFileSystem with mount options
 
index c161aecc30f09a7094e582a1933a11d951658765..2ee5c269f9f8fc4cb61a54c38974a27b46618f86 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Test for TemporaryFileSystem with read-only mode
 
index bb830595bc16c051907c3890bec5ee4f8b6a6a62..ff0aa048d49740113a6f03e648bf11ea8fa84567 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Test for TemporaryFileSystem
 
index 05c1ec0694c4bc5c5ffeaf272800a0d269112df1..f62ce1a85204b98b9beb98b921cb052f12ccbda2 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Test for TemporaryFileSystem on /usr
 
index c18293e403e651b1823dcf0f5624972ccb2e3c3a..380cb8234a1a77267b1ee955f9d70f64f4cd8d33 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Test for UMask
 
index bf0573dd42279e5f96a8e8a4319791833f3baf47..b28023d8a9588e33a4b072de0fd0c000a0e8b075 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Test for UMask default
 
index 5b0123b81e4596aaa75933b62ac6a4a18246a868..b79e3d42c7ec2d318a693ce2877f6e5b3d0c99c9 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Test for UnsetEnvironment
 
index aafda3aa26c545540085502cba43bf7013110ee6..8f0943c282e49990c0a93a08908b5f10c8ed5755 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Test for User
 
index 0a00c1abc4394713bd2c7ba780599fec30fb8fe2..834d11ad319e92c14b616588c6bb8a5eeeaffbe8 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Test for User
 
index d315a828d4df446c6725129f0b708aa8726cdb4b..b9863d2025ff248d198d902867b5c72763b2f5e6 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Test for User (daemon)
 
index 5c807b31726a212a1412e25d71c0be7e7687ccd3..130d9d5c507d31db8e0199e7243f715b98cb3bc3 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Test for WorkingDirectory with trailing dot
 
index fe3c420d2d3c3ef1496ea61055e7c20479ef0b0e..b53bf6081f729ae2c46c845715622c9558028bfa 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Test for WorkingDirectory
 
diff --git a/test/test-network-generator-conversion/.gitattributes b/test/test-network-generator-conversion/.gitattributes
new file mode 100644 (file)
index 0000000..6df434f
--- /dev/null
@@ -0,0 +1 @@
+*  generated
diff --git a/test/test-network/.gitattributes b/test/test-network/.gitattributes
new file mode 100644 (file)
index 0000000..e99a2c3
--- /dev/null
@@ -0,0 +1 @@
+/conf/*.key  generated
index d85ea5bb72d573b49ab600d251d8d1bce26963e9..074ab173bdc022362505875321bc7150411bed7c 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [NetDev]
 Name=hoge
 Kind=dummy
index aeecc1dc015437dfd5c79ef2b46fa65d6ceda034..877231d34d15aca04d174fe86f1a56952873dfcf 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [NetDev]
 Name=test1
 Kind=dummy
index 6797eb4b09a02e44c42148981462a35ce5dca916..86af17ff9f1279e0b7e125c20722d78d1d21e5ce 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [NetDev]
 Name=test1
 Kind=dummy
index b117028a8484afafd3ad2ada9554c585e9f04611..0a4511bfb31f454c36e3b46aa5063fde9b346be3 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=test1
 
index cb7965c37a80ab382df5a8f1bfb86ef4b2c04d79..cd08d0f5c9b73cfd5ac789b1a7d4aed61f0f872f 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 OriginalName=dummy98
 
index c51d2a47a51be379780ca240fe53654fe76a5391..1320b38bf0becad13dbf26761154a6a2cb016830 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [NetDev]
 Name=dummy98
 Kind=dummy
index b0b0eb65bde7b859aa074cfd7ba054b0577aa1ff..b00ed4c86dc35655ddf42f1f59242b38743babf1 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 OriginalName=dummy98
 
index a7fdc0f7e014a327b53ca544c20cc50f6f99ee73..d0b0eca42a93504643e0920071a8b6bcb4a02838 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [NetDev]
 Name=dummy98
 Kind=dummy
index 29ced8b90ba8f8f7fd92abb97251bf55f4748900..6643be1409adbf8078247bb77d9e197413deb7b8 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=dummy98
 
index f0a530e9dbeb7d3f89315726f3449a550460a491..a7d9fe9f32a8c778e020b94bfc9657cd4b858643 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=dummy98
 Property=INTERFACE=hoge
index b632af166a07aaac2bd1ecc3265b763cf3b11010..23b222aad7334d5b74a611b137504ba6f4f6da16 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=dummy98
 Property=INTERFACE=dummy98
index c9d18d76b629215cc205fe8f51bac87a801be8ef..4b9feb1b95c4197e6c49104c99485f5dcf0da43c 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [NetDev]
 Name=dropin-test
 Kind=dummy
index 674c1f516b3dbdf43f0e19e8b18730b2c77431df..fdc81ea6d6c6de176e4c51f8f9a45f53c58bf08b 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [NetDev]
 Name=macvlan99
 Kind=macvlan
index 2c23aacfb2a4d749397a829b9e73f66da0f038d0..96559253665604ff64f6665a3e6e96f580a67192 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [NetDev]
 Name=macvtap99
 Kind=macvtap
index afe1debe081b766c2f79663e3816bc13e6893fe7..d7c0378532f5687af3a5fded03af6f2f4a12c899 100644 (file)
@@ -1,2 +1,3 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=test1
index af39404b5f2d070c6d5812017c8a062b282a4b7e..0d28187abb21a8a239ba94878e0b8090cc1d8641 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [NetDev]
 Name=vlan99
 Kind=vlan
index 3edc59e7959eddf270d7b7f74c1044c284a5d3d0..6536b7be51b5eea8c2e9570cbea79ceefd852560 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=vlan99
 
index 59a65960e9f7c6cc45997897706df2f19bbab786..944eff5d1b9177be9b3adb909fb641b68a62cf54 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=dummy98
 
index cad651156646f76cf9325384b12f7e08adcbf1f6..9f4879ff24c3f28dd8444e24d55df3461022e8f4 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=bond199
 
index 9edaf871b4cc1a12c8a3317371b154c105cdec58..11b86bc2c0828133cb1e8f8270047df5711873f8 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=veth-peer
 
index 2d8371ccd0ff78e039a3e533ace541d3c23e47a6..2ffb9bad94cc6df73d1eac4f673340f8a3862ce5 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=dummy98
 
index 380ae267a2b083e35c757847d56d0e4164b1460b..bf84572bd2b2c7d69cde976b6fd3f9ece2da665b 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=dummy98
 
index 7602927d81878db61cfa04b3fa7100adc0d46e41..5123f313689cd73c0c915376d813b52e82865335 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=dummy98
 
index 84723138f2186a9c8db8f9c4fcfbae18a8318948..d5352e2720a9f2090fa6b4d08761c338c6e5b143 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=veth99
 
index 5c37d2f61f51833075591ba9f5d84953c0f18de0..91c48149bde2d77836530478788b5b948a294f73 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=dummy98
 
index 756beccb7020038348e2fb51909071a0ffb3e593..85f5e0d0f5340ffd3fd08df753c69417328b1145 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [NetDev]
 Name=sittun99
 Kind=sit
index 873e260ebf8ea0606686d7aa3b41b37e3ff2b67d..a9294d88a0187098e6cf1545735b4c6e2d38b6af 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=test1
 
index c8af4bafc836e17ab29b5c53af4c826778db2945..2abe2f766aca9a76afd82bc880ea04f7605c11b3 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=veth99
 
index d6ab3402714b9c969794091ba467ee613dff3003..644b23fd608c52e33d520dc091709f902ddcd210 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=dummy98
 
index 362ea25a95d207d95d396a2207d3f7f9344b68cd..0108d43e4b468bfa1a3a39f33a4d6bfd79428d15 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=dummy98
 
index 6cde669dc51c8f6c19bb1e5f51783959928576e7..209a8553b9a4c1866fb7e2f1e92dbe847b026200 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=dummy98
 
index 2e76709d885dbbed9a4bd203d52e4bc2edd92390..4fd924242a804867112f6a5db663c6eed693106b 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [NetDev]
 Kind=bareudp
 Name=bareudp99
index 92e77d4592091f673a5682179ebd884d21e4151b..06d51b0f667203f7ecb5921c4f8517e232364fa2 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [NetDev]
 Name=batadv99
 Kind=batadv
index cf854d35173f2ced40542003e7fa396eeb90f9b8..81517f45e503fd51f03f76d8178d0883909f9008 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=test1
 
index 1bbbf755705b1f7bf38aedd363c05cc7e1e29c5b..6de54979ce6f9f0cc233b5ffae7ec44cf101ecb7 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [NetDev]
 Name=bond199
 Kind=bond
index 7e6a9edc69f889120076e70bf6525a7afaa6107d..67829f3e644ef656ec401d4d6c7f2a31728a33ff 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [NetDev]
 Name=bond98
 Kind=bond
index 4e4885c44c7a0cbed44e8084a32a41f890fe455a..ff0222a79ed896c5fdf57b473a57e5c50d5653d9 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [NetDev]
 Name=bond99
 Kind=bond
index 64c986d493ebe18c0cfa4d07808151e237591636..6a8d491f3bf544766e5d8550e56367bc09f0ea6b 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=bridge99
 
index f5c93516379ea236532fc156f31c45d61070b6a6..6d8cea9021cf6310bdd2dfd52623833c33eef521 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [NetDev]
 Name=bridge99
 Kind=bridge
index d2f346388d30f10168f2f0e0a3fe33bc9e1051ca..c71889249f5d8e807f6ac6e7bed95582c483c31b 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=bridge99
 
index e9eb1c1cfc3cf0ba42958063e92582d941f131c9..d16983cbc3f100f7f42ce31cbc81709822af1563 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [NetDev]
 Name=erspan98
 Kind=erspan
index 86935e998ca73b2b41e89515356f0a79855e4a72..7127488439a0cdda9e6ec53e5f6b04dd18874e1c 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [NetDev]
 Name=erspan99
 Kind=erspan
index b8b368fe5aa168ec82ed0cad6ff810f367c33aea..3d4cbbc0ff96db7e43ebec2c2017d12a91ee0aa7 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=test1
 
index 77874b34405c1ca8da2ae4fd71ebb165d57ef402..973225db3da6f537eff46f3b2c3ff668c579f6a6 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=test1
 
index 44716e396a0ea9fbaca4832bec33e2c78cafa7f5..a363d8738cea475bdf625030cbff43f97aee0aac 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=test1
 
index 6ace606ed5a9a1b2b7db7e991ebac965e0eda7f8..a2d36d95f0ea6d59a94a21467b5f0a109d7f8eb2 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [NetDev]
 Name=gretun96
 Kind=gre
index 97fbc13d3cd96ab3d41a672fd749dffb53b8cf22..7992bec7fa7b870ec73f7612ee1d946fc475fe73 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [NetDev]
 Name=gretap96
 Kind=gretap
index 2f52157490a4c644b8ed137170353c5468f7edf9..1a98a401ad5872a08bc585d98242173b85963a3a 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [NetDev]
 Name=ipiptun96
 Kind=ipip
index 09ecd9efb454e63604f9ddc5ae72c231de114d96..d48bb87474fc3a8acb6312869eb4e209ce727470 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [NetDev]
 Name=fou98
 Kind=fou
index b00d5ce5886529b3a2505b24277f878c2fa6e2f1..8aeb40bbb9d5e0ac711929b57f7c56d355d043d6 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [NetDev]
 Name=fou99
 Kind=fou
index f1b4f32574c67dd6d14f4c990e82f20939bd7603..f7f22384cf518f1b8969f9db612ec4e5170e97ce 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [NetDev]
 Name=sittun96
 Kind=sit
index 908e58881efb23b72d75767d1156cd6ad2347b63..2e746647ed0ab184350bf382873911af5a2fccf5 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=dummy98
 
index 1ea184fa2ff864231819d963ba06d28d98be5a41..3b43f5628a8e52d5a3ef1651953e2da67c1f303e 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=dummy98
 
index 279d71324ec52389d42522c3384bd0aa79e33d79..ddd5ecbe4ad23682b6f8b6eee64161eb39818d37 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [NetDev]
 Name=geneve99
 Kind=geneve
index 3467b169fc9c1188b264f6ceef8a628264e74257..58b2bb30f872d65ab8edaac7762a3b04c007c2bc 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [NetDev]
 Name=gretun96
 Kind=gre
index 36bc55690aee8e0b437460173c77a4c43d1241fb..120bcfbe63db5b4fa9f8d6a6928ea0a2a5454e4a 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [NetDev]
 Name=gretun98
 Kind=gre
index 74c02c9c827b9dd255739d8cdecc8f849769ab04..f94578f06d7c3e82da531ade000ce5247fc22a18 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [NetDev]
 Name=gretun97
 Kind=gre
index 89c7fe1266c9bb874224166207d1dede0adfeff1..9fc2371f21f64cf770956689c22d73864c844ab4 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [NetDev]
 Name=gretun99
 Kind=gre
index 17abcf69fc92e8f3989fc06e34daa5072ed04f7c..5e3bd828a10af7e8397b724955586cac269d19fc 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [NetDev]
 Name=gretap98
 Kind=gretap
index 912daf5bf148dba0fbfb48f48abef277a8fa472e..86ac3f7c5b196ca9f264937fb763c067e8ffb551 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [NetDev]
 Name=gretap99
 Kind=gretap
index a4ba771967bd68c5a749b4357e21e2d566a7c4b4..e166364543d9c17fe675d242ef45bd143aee8a55 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [NetDev]
 Kind=ifb
 Name=ifb99
index 519474feed2cb137c8aac162672a15a49a036451..67ebdd018de4232353669b485738f99552af14b0 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [NetDev]
 Name=ip6gretun96
 Kind=ip6gre
index b3781f027cd144a43aaeef5e7da2d34c25cd0547..6d92129a315f5a08e922a0416e93e4066ed44c01 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [NetDev]
 Name=ip6gretun98
 Kind=ip6gre
index 828c17f2a65405651602b8b14f6c320658031a52..b242e87a232effb9b0e49f84c6ff8de1995b9baa 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [NetDev]
 Name=ip6gretun97
 Kind=ip6gre
index ba7d2bc372a327032698fe69779ac5275924432a..deb1b2999e038ffad4445e93caf225585101914e 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [NetDev]
 Name=ip6gretun99
 Kind=ip6gre
index 7a962e8a8e0d7db0803a15ecdb0949db02454931..f1940c2828b9dab1606746d4fd2667bf537d8f4b 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [NetDev]
 Name=ip6gretap98
 Kind=ip6gretap
index b16e0b4969e00dcea3b94b45cd39921313b6976f..09ea1162f13fca8e594f6cc3ce8c7db1b7274f5d 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [NetDev]
 Name=ip6gretap99
 Kind=ip6gretap
index 7732eb88198bbbc31154612675ef9f0f07ad4254..3521d33104803ea3838d51b52fb6c5ad939a970e 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [NetDev]
 Name=ip6tnl98
 Kind=ip6tnl
index 0d9d1e90072af31307b1e0e49d8a7859c11d0b15..df22dd829b156db555ee72e0375c34fb06fb039a 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [NetDev]
 Name=ip6tnl97
 Kind=ip6tnl
index 713e685ea1697dd1ffb56870fbb16fe97cec81ed..486bfbd142964e5c7c698880bf0289bd173ba6b1 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [NetDev]
 Name=ip6tnl99
 Kind=ip6tnl
index 8803dd12e994ecffd0bbfcf208e78bdeac6a2fd1..414795a3d9b943098ca6ab8321fbb7fef9e52d86 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [NetDev]
 Name=ipiptun96
 Kind=ipip
index 9ee26c90c86cdf54eb6103e792dd1e5bedbe1ff5..c675029acae630cb90835ffc2bed23076deffb38 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [NetDev]
 Name=ipiptun99
 Kind=ipip
index 36ff8d94297a41c820a634891e2db3273210574f..757b7518748cca2b03a9798b75fd6c168f4e5207 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [NetDev]
 Name=ipiptun99
 Kind=ipip
index 8fa27e82fde19471a232b49bf9854657497ac746..3702cde7b0c8ea0d9cb850a6eb6c6a88b0f61595 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [NetDev]
 Name=ipiptun98
 Kind=ipip
index 58d7feb61f1010786d72d37d80ea4dfb6bdecd32..792d7d3bc5e5b938ea5571800a25edfa769fd5f8 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [NetDev]
 Name=ipiptun97
 Kind=ipip
index 159ac727030f3673946aac187e455d17d296f88b..e31bfb6c437dbaf94b993ce23116dabd3675faea 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [NetDev]
 Name=ipiptun99
 Kind=ipip
index 0742ad58494f13d5e5c38e818f674c73be9562ba..1e3f47b567b719687ee42f1ebec82b0886af61a1 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=dummy98
 
index acdcce819ae1d8018914d811eb9b80670c7e73e9..81302abf9d6a364466267d95e748b8e90f613eb4 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=dummy98
 
index d0f0c9a87e0c03405e962baa143503bf9032c140..0b1fd4b2c01bfdc40a786ed13914fe498e73bd0d 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [NetDev]
 Name=ipvlan99
 Kind=ipvlan
index 2e40adb7ce10c9ab22341fe2887bdb17d7897e8b..fd06264a350466eb807418fa70cb4935bc88c602 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [NetDev]
 Name=ipvtap99
 Kind=ipvtap
index 3aa882a2618ec19d94f5f1b46871d6fba16930c0..9557e277095876c53a9e5273b26f3916e916e277 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [NetDev]
 Name=isataptun99
 Kind=sit
index 9f2eb9095cb9b86d9ff8fdb0cc5bba609b2a9743..d00a50daf6f3d09aad37d495161b39f1c0b26a62 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=test1
 
index ceae25fa5f880a9aac2ca08434283352d7bc13b3..1dd061894fd7ce7c187dc23112fece15cee5fc86 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [NetDev]
 Kind=l2tp
 Name=l2tp99
index 84589b0b269d0d5969861a92b3273c2654926696..81d9ef51fcdeb7b909a3a46f93230ba55e49e826 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [NetDev]
 Kind=l2tp
 Name=l2tp99
index 062eaac271a4265e01a16dfc1e3620a50052af97..412f6d596f5259b6044ce2af7d98200071c34260 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=l2tp-ses*
 
index 8320414d9ee737453ea2db65829378aca8d80ee7..a6974bab421745297582f2f6884ab51eb7834b76 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=dummy98
 
index f21d4d2328c84d41440a289d51bc098e287ee59e..3c99de1f0224cedc75f5ce28236152849a644cca 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=test1
 
index 4fe49160314d403b94696e1586aaf3aea73cd764..f06b6154ceaa306655f3b191350883d3205b1df0 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=dummy98
 
index 9b603ca03998b626e7bf2694949c4b88dcd5caaf..9036cb54634502c6f12a7029e6910543252acd41 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [NetDev]
 Name=macsec99
 Kind=macsec
index 6def92f6d5d79f47161f7c4abb8967701b661d90..4dcccacb92f8516336e47fd67e9c40eca91da0af 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=macsec99
 
index e02c55e3a047aaf86a6bd1833846d4b847dc8a71..f1b115167031f481ef42a83990d38dea53f0a89e 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=dummy98
 
index 8865ccd9724f58024e287623f82587e972bc6876..8ef6e3f28b51b11dbe2d961e72cad679877615e9 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=gretun97
 
index 322f73965d94ffa667e23e23ab78d396db97a508..f7480fa6a2228b998d9f4fa69ee2981a93e0f9ea 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=ip6gretun97
 
index d0591d5875835c74fff82514f4cb03f84c1f792b..6911f4810d48b7e36446769fdf92087f81f4d4d1 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=dummy98
 
index 94c04943b717b41173d5503db5b7204c0f57e52d..38f6b025166cdeccbca9f8ee6a0bfaedce7f47b6 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=dummy98
 
index 9d754bf25a3839b6ca382568fc7ca360df72962b..a7bdaa96635a5bcce9f47cc6b069fd4084c06fab 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=dummy98
 
index fdaf32d53408998d1a26b6746f52bd7405570d03..9481175e2f4c389f8867fc5b1421215ea074f0b2 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=veth99
 
index 3e87bd40a93d25678259348867de17ed55de1e98..f53a58b0597e10b11de002590b69c27c7e233139 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=veth99
 
index 2ae6b12425c0d378b32a01c13fd19218a6de78dd..5e344d92b58048a9b33d1c540d977227f900228e 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [NetDev]
 Kind=nlmon
 Name=nlmon99
index fdc1e11c5e1996a07a6ea42ad4c010d2a49092b5..ac41a32ab0a12569f99d44737e3ebf510595d6bc 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=dummy98
 
index 9354b55d5cf61e2f79462d57c6d52c95ac394b32..d5338cebc557ff892ec45ab47aebff066b95e427 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=test1
 
index a1b00f258ffee24aabff1191027fd50e233e84e1..9220a20bf56aea0adf2c00bba569de7bfe81dd62 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=dummy98
 
index fd2520db505b08b8d3ec8ce8b25fced4ed344d77..c91666d32325970799833a9aeab707f1f39efd25 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=dummy98
 
index dff8b0978d73324945ca98720258554c0450a9fe..b5fca7699dcb47d7d6cd52e5cf594fc0e369cd82 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=dummy98
 
index a8c6b68235b303cb65db0be8793139d62cdfade5..81ca718393e8752dd3729c32b0c91b5ac4380d02 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=dummy98
 
index 9ba23328c81c10bce735562040a8c4c29f392972..5f567d39473be811dd7d55929d3d957e938a2ec5 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=dummy98
 
index 950536259fcbffceb28c438b8bdd6363a83b757f..0b1c9d3990cd5a747c358c80c88c6fabb73257df 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=dummy98
 
index 51dced2329cda51ae140e1c7e1770901b332edb0..d895f7f34fe5756b17e70fc807a2b56f760dd959 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=test1
 
index d41ceba3eff2a31724d43488fa2fd6afd96898f6..119423b2e7e298065a1145a44c36b91c609a26ff 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=dummy98
 
index 3a24415c1295dbd7421771970de11bc3fe5992e1..1c8dbc2461dfb916a084cbdb6b473391c452e334 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=test1
 
index 4e551c024a512b2561fbb9914a79d9f12c4495a6..f2f8e457442430dd1fc833b3379a3a53885663e0 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 # This test cannot use a dummy interface: IPv6 addresses
 # are added without having to go through tentative state
 
index 94b2e8730fd973842cebe8fe487bfb2da6d5c26c..8f242bd1fe511ad9ae803e6966c34eadcb08e044 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=dummy98
 
index a0ba93e631d1469f909e99e9072f050cdd406952..aa1278125161309b7097c95e25a1b3abc796cda5 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=dummy98
 
index 038dff21aa486d79cbe7fe822dbd028862b294e7..1bc94f930fe970eff071c4e9a7b21d9d2edc5e65 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=dummy98
 
index e961dcbd3806aad1ad75de4e0c0888993f48f265..a25cf3e7046a0277b7b386874a6208c7a8f49936 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [NetDev]
 Name=sittun96
 Kind=sit
index 20c1a334a5e498c0eae53f5e5ec7809a5732af9c..3c92ccc9bd20d08954a5037cca9e765e2cc48e31 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [NetDev]
 Name=sittun98
 Kind=sit
index ed7b9b749906c2bfd3eb0a8a49298c85e83a882c..c8f18a6f3e5102b78973d8aff1e5196204a961a2 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [NetDev]
 Name=sittun97
 Kind=sit
index 406d74bcf02c4992e0bfe869d983cccded7e33b6..12157973b0e34c74371912fc35bf98bebee4892e 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [NetDev]
 Name=sittun99
 Kind=sit
index 099331db5053c23acd393871e203722df8f59612..d87615e44470c4052032db2b17314c1cfd2567f8 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=eni99np1
 
index c4c5fbc12945eb42a9771a470e19ef2817d2c5f0..9e423c432dd19c35d8e6c0c95592f19da32dab03 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=dummy98
 
index dc1d6542c0e2c5b099b42c279b20cd8bfce862a4..72575eec8d8618f414c3c433b60b8d28b55571f3 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=dummy98
 
index 3876075a7a62d60b0af66d1aeb1fcfb28b0289af..5c1f97be9ea306356966c3fe24657db47f26227b 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [NetDev]
 Name=tap99
 Kind=tap
index 0af564b6208a43ab000f16ae0e07df5aeb0de38e..c7ad4317a3d3396bf05c842e0ebba6649a4cca82 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=test1
 
index 37459c79701b109c47698f8b1fb953de61a6089e..ed25026a95925898311312939ccfe0700b58ebc4 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [NetDev]
 Name=tun99
 Kind=tun
index 7a9e39e9d2e89ff86ee0bb26f692229d4c48af76..8ce56a340245c69a848eb44f9f01be9193434c06 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=*tun96
 
index 8ce05adbbbf5a7f0f317984e2730162b60d57c37..e65530e096487ab486066538db07d9987055c710 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=*tun98 *tap98 ip6tnl98 erspan98
 
index becdcaa8df5e5cf4b1875b7842c1b5c776a41c61..eb7bda9c81893b47c4ff8d55a38fd80061f09cf9 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=*tun97 ip6tnl97
 
index 32c19867ad49a943bc33c2f98e0a19e56d8abc26..9e269bd3753be5e517e0b2dfa00b2b919daa442e 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=*tun99 *tap99 ip6tnl99 erspan99
 
index ff1979536ad49d03f647cae972b3258b6d428c35..29bd98e5c9d0883156ada54a3c11da13e1d5bd22 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [NetDev]
 Name=vcan99
 Kind=vcan
index f24956fe4e645b1d283306c9b482aea3384f00f5..d5cc6d3334b883d1379f902dd156e69725393b7d 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=veth-peer
 
index 9ae4ad53b87a5633a64de18a0de42057f672ac67..84bfa8f5cfeba1cb867c34abf920fd91f3b089bc 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [NetDev]
 Name=veth99
 Kind=veth
index bf949ec293a87057a4ac48837cfafff18cfa5389..001ca874256d31b62c6ddeb14f34d9196d6be10f 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [NetDev]
 Name=vrf99
 Kind=vrf
index d47ecf078968e56322b480d2d5dc07fd6d8c6668..914efee8c59947e5b1e8aa0aebaa8d579b57729f 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=vrf99
 
index 3cac374bef22a3080d69d7cf78b18b410d824b05..e1e1d65479f64787ed39c0180fd37ff9495cbf47 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [NetDev]
 Name=vtitun96
 Kind=vti
index cab3886430b0a795b06d5687753f8b5137d63c93..c1c94cf1195672b895fd31833b533d9ab883c221 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [NetDev]
 Name=vtitun98
 Kind=vti
index b8bedffaa2dfb4c040f37723c67b7865b14f70c6..2367ed9ad9b9dcb235957486b891bfb5ba13b268 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [NetDev]
 Name=vtitun97
 Kind=vti
index cec625978150ebfea97072a844efd258b7900007..5a8a1ceab6fc48dcf90bcc8900ad70045b29e194 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [NetDev]
 Name=vtitun99
 Kind=vti
index c3d05b4f5850e5ae96a0169826b80903d7a7eb1c..546999fd62565a70148620415ca2e025caed5354 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [NetDev]
 Name=vti6tun98
 Kind=vti6
index b86c628abf6ae940a4566a315e28992770cebf6b..6f333159cd0d801416e14381f22ecb03a665b5b5 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [NetDev]
 Name=vti6tun97
 Kind=vti6
index d150c9ce86a942c429508cfe49261cd6564d4ebb..68cbcbfba95eb18543822be6f2d1d3d2cfda32c3 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [NetDev]
 Name=vti6tun99
 Kind=vti6
index 6d879b15e35f557c4860d4b520f4df8ed0ffec7f..49c0a177941edbd43a388e4dd34382b79b0acadf 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [NetDev]
 Name=vxcan99
 Kind=vxcan
index 13b6cc8e7ced792d9300fe889fae3459b011b19b..44b819d476b1d2bc0c2919898566d8f3c04d1b2a 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [NetDev]
 Name=vxlan98
 Kind=vxlan
index 95339255da0661eba87cb68c489ae5ac64c2a2f6..b5079fd341d8adf16259f9b0fe0c00f733d4ef2a 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [NetDev]
 Name=vxlan97
 Kind=vxlan
index d5acf48da5b56cee4aa72b40e24f04cc9c1f2534..0b41fc597e33ce25647e9cbf4f37078e7af0cdb7 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [NetDev]
 Name=vxlan99
 Kind=vxlan
index 61a75e592f4554d8309d0f2114e4c10f074a3aed..90ea1b94502af19b45c9420027d81d6bccca2d88 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [NetDev]
 Name=wg98
 Kind=wireguard
index ee70e3c5e8c89e07817d62f1e2bf6a605631361e..33c794c2679f5facd15f3b31bb1d9a74c769a723 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=wg98
 
index 13fd55d2fbedc909f1aca3f8d7948e109ef660ca..ce3b31a5cecc134bb3254a25bff5863fd38193bf 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [NetDev]
 Name=wg97
 Kind=wireguard
index 5c29d643f5acae974c84ed7314ea462c001a9f68..62238a1223071a89caacbca11f72b8787765a875 100644 (file)
@@ -1,2 +1,3 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=wg97
index a95ae205d71a53069f8c4114ecf2b8900970f733..075f2bd6a8dcb2f638da254b71306bdf8b2c979e 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [NetDev]
 Name=wg99
 Kind=wireguard
index 565e85ea8d5ef35b8cc173d8cb9aaed9c6104608..d3b0ea4e6ce1c85e0f08ee5f4f2176320a1cc704 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=wg99
 
index 8ed4321493b9756d76ae027246dc43c2176407be..b2378849d166c08c9afff64cc939024c41c5e990 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [NetDev]
 Kind=xfrm
 Name=xfrm99
index 81b32dea60281701b424ceff629e1a8b0f07d99f..353bfb70037a7fd9f9fe76358969fcedbf958c10 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [NetDev]
 Kind=xfrm
 Name=xfrm99
index e1196b866b4d157c54a18079da596e3b83d56791..ad7f007220b6bc83154775290337586091ebe121 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=bridge99
 
index 105012a619c1a8dcac4122a497c926dda0ada504..4ee5ba0f605fb461890cbea06596359957c155f9 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [NetDev]
 Name=bridge99
 Kind=bridge
index 3fa1737f8167d66a438a4ab7dcf2ceb5b762cd97..d92762d89975b62ff7ebaf39cb90cfc7758a4311 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=bridge99
 
index dbada0b130cbf41b9c7d3a654f9ac74c727b0375..301d22a653af6b0652e3c281b18e76f4d38761f9 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=test1
 
index 6aed1785258dcdc821f717c17583afe827d6642c..07c82845659321d54d36fc3d6c1b7701706d9195 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=dummy98
 
index 5fccfec5d129938760b2f519b98d6f182b7e6444..26ab7d8af6abba835ed9a4842fe8d3e400ea6e58 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=test1
 
index a74ff55333533df208cc4a05ba4e5e48b1a11572..7a697571e8200658f09ac9b92d203a7b7351f054 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=bridge99
 
index 8493e32525d2d4f5aac2ae598872005346f03e3d..4bbbc5660ace599cb136757d09070db706372f20 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=bridge99
 
index 5a3c88c29d627fbc5defbabe5c1f32dba0b8ecf3..876219fca27b970d3a5fdf40c30656d338bbdf70 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=test1
 
index ba50508afbd07fd33e357a142ddf6579c8973648..9ac851030dc5fca6f4f546b8179aec411e52ef2f 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=test1
 
index 9b31e06b5b73c81b7e18c38ad2736b33fb2a89ec..fda9cd6cd89c75fcd86759f84f79e0e20506db44 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [NetDev]
 Name=bridge99
 Kind=bridge
index b4b5362a4a580ab0549c487294a0620b0112961c..931341b01c662ac4dc8328cae09440d2144244c3 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=dummy98
 
index 96bd561ff90f7455cca04f3667b43d57caf1ed32..0caa396bd4284a4dea9463bd78abded008e90315 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=dummy98
 
index b053c2c6b469524605457b99eead7141630cc541..e31108b3418bb42636f6f9a47e0cd8013d503839 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=client-peer
 
index 7787bb631ff247fd1465a09a07c8be0fbf000924..cfa7e5a17d28791d9c2fb5c3d90c400e5e79e81d 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=client
 
index 6aec2974a87ed47204ba36549560a4372e992d0c..1f6fa4b5bb1781392e0715d3d008546be3c78813 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=server-peer
 
index c8da15c3ec8bab49b54a43af361da80e6945ac03..905508f55f1c2015579b4964f87a5e636684ed86 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=server
 
index ace785f5cab32e49502294c152ab0a3405c3f1a1..e52e43a193e5eefbf0a65d9a9ef7016a0c50046a 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [NetDev]
 Name=client
 Kind=veth
index 3a3d3931ba681aa8521ddef3bf5187b26a9956c8..1427024d4792babf0633d5126ed56dd961913d44 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [NetDev]
 Name=server
 Kind=veth
index 4eeeae201c9f7a2c4d17769e202db8e25b9a370b..12228a3e5d23e23fb48fea4566a314354d2771d7 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=dummy98 test1
 
index c5b417abbcd7b27480368555b89774e508987170..09da6a0c3530a0cf05f58987cac24ed77d3d6bc8 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=bond99
 
index 9797e2edb613c5b5123455627918e49cb4aa3eb7..1c1b34246c6d42f38db3355816f97b346240eb65 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=bridge99
 
index 1a00ec10dc8e688125b69f67017e172c2085b56d..07ef254ddabed4e6ef239b76e152f2d58067113d 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=bridge99
 
index 8228369887eda0720a3c8f66d64218621cef7dc2..b8a49a0378a567ae5384334068f8a19a96051ed7 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=veth99
 
index b92bdc90a9e4fbb6553304ee9d2607499cfe5ca2..fb356ce14540cd0426587ac2b029d967f9b78629 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=veth99
 
index 123a459f7f51634acc812c0a8863f8b14f6bfbf7..ea1a2d0506d1f7bdc424032d186776238c28ecd6 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=veth99
 
index de43c16d118799396f9dc1feca8267148b678d23..e1c7d6c062d5601f37b980e41ba183d4b6495079 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=veth99
 
index 604a953b5811364b0bc8e647f2532b2e76017fcf..11a2fee05034c0b7a1818caf870b7ac4c7e62d31 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=veth99
 
index 63e6e3a048192998af454ada8fc65b068093e389..e1330516413eadba2ab3e2d4283e0d00c5dc174e 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=veth99
 
index 5352956e7e5d42d2516739192f893686159c65f6..f144013e9c3b66538fedbcbbd594b89f5b47b97d 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=veth99
 
index 384678cc7e052ce389c8686725d2d013e7378608..228cdf3d52da299be807eaebdfc3b5aed5d229bf 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=veth99
 
index 9bc019a67471d205919ad9385868d6bdca15ef19..797d56a2637f034e5179d40646f02e10326e725d 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=veth99
 
index c980bf9fca5ccce1c4897edb1af8dfbbb47bee16..43702d5987fec1bed5fcd88037de065e649a4d72 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=veth99
 
index 8b2e934f7fbf94fe5df1d7f6f21bc9651b42fabc..f2874281f851fe517bac9d3915facf7f02f654a0 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=veth99
 
diff --git a/test/test-network/conf/dhcp-client-ipv6-rapid-commit.network b/test/test-network/conf/dhcp-client-ipv6-rapid-commit.network
deleted file mode 100644 (file)
index 72dfbf1..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-[Match]
-Name=veth99
-
-[Network]
-DHCP=ipv6
-
-[DHCPv6]
-RapidCommit=false
index e17c9854021e0261546ab08400db794bd12ef50d..9a737f32c1d7d182ef19e6aae6c83bafaaf845a1 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=veth99
 
index c43f78d1dea2fcaa27f66694eea83a7a2970ca05..c72af5628d429c6d598dfe20d6c32bbbe2a336ff 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=veth99
 
index b7d779dc43bf8c4c4bade81e8b9cbeccd6925dd4..f51444a20dd966b2099338aa32573155951e7486 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=veth99
 
index 829b4804f80676909fa1ceb6dfdc9d4efdf09e32..4bf69eb2c0e278247758c310dee1a17c92974f63 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=veth99
 
index c662e99753768872146c55146739d4f193f18913..8a8b087bf8e960a17e2a1940f816735fba4f2612 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=veth99
 
index 39496d9a279a377cd1ff39e75314ce9d8215b6be..74613cb8390f948d7cdb83435ccdcbc7ea8cc031 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=veth99
 
index d3a442e486979bc4f210d45601d382d3937575b0..94aa1fd12cc510b5b6cb1e5db3965d3f01b659a8 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=veth99
 
index dd0b58182229ea64f617909f2ec12ae09b84ae6c..f9405f8f29711cd3ecff275b8526003b0d757047 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=veth99
 
index 9662c00a23d355d598c0d92624aa27d4436dfe3d..ae04827664e4de2eaf3b87ca7f96feb294caa1f6 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=veth99
 
index dfb9f752be30ffa715df242be62caa36da4c9a18..b11a578cbb3a233eeeef886c256b3710d682022e 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=veth99
 
index dbd0f7f3fe01d8e02e9a4e5eb0e59af32cf84b6e..5fbda20a906f073f55407ee26956a84d0a6ac662 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=veth99
 
index b928759c7797aeb7233966d75d298caa3a8510f9..9b651c16ec3e47a0a204b3f53d042047ac6fd054 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=veth99
 
index 4655b69f1aae418f929c475c1a1e3a32f72836e3..787a84d079ae19b2774671e716ee198140691e3d 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=veth99
 
index 0d0e2dd7b63e2064f6bbe0609acf2397676cd5ac..af321d87c2424baf3ade9ae2991941ac4edbad9d 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=veth99
 
index a277d5ecbf15be8c412b11d91d6ae2106f49b895..98388ebfba576f8d3bfa9789902aa62d98b423bd 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=veth99
 
index 0455e09b4c7be79b8285914d81d3cac91e4b76c9..5a810260659471da43443dc0cb25abb3140ae7f2 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=veth99
 
index b4e11bea096b33f29cc6620d978eab41623fd0ac..7c9d94957ff59a31b50192b4c1fefd19221bac3c 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=veth99
 
index 5629bc48e42ad674761b50ed4f42230e96af81da..c63383941043961803dfef8d481060698e70f18a 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=veth99
 
index 2c80e88736d024020756690ffb5e839b08ed5ad8..cb8e04ab0d508dd99534a745e0a8975eb65e91e8 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=veth-peer
 
index ecd91cd19c22fa39c7652f5cd349f968227d822a..1f2783dafdffb88bf22518f42995b7bdc7944091 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=veth-peer
 
index 8ce4777e67744f2490186610794be17f44f10a5e..89a8db15c8159881c4019a962dfe7f56aae119ab 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=veth-peer
 
index aabf69debfd3cdf493669aa84e2b78c4ea616798..59e0b6a323ae8aaa86a48c489c3c4398a59f9402 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=dummy98
 
index f24956fe4e645b1d283306c9b482aea3384f00f5..d5cc6d3334b883d1379f902dd156e69725393b7d 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=veth-peer
 
index 4c8903513919890526253827e1792a77a488287f..13ee90dd5e354cc49a007e9439763b34c950a1dd 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=veth-peer
 
index c3826a751e4c148e5c686edfdc5b0c67fa5ff328..07ff0f65bc32407a41fe35a14f9e1276803509eb 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=veth-peer
 
index 4d4a815a65009ad06425fff57ab7f95d28c06539..7e1f56018a347d78933b25652ae5d9e5fcda042e 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=veth-peer
 
index d1a88cdaaf25bea770c6279886bb535d6f4fc5a1..c862baea8d139d94a80f8678799c0dfdfbaae4ea 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=dummy98
 
index 1deaab45d6a7414f0d7d0157ff762fddff2a4f96..5e940ed721dea63a83bd5545745bd06764ec3693 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=dummy98
 
index 68d95b18080c1199cbf1e0511461ebdffb425966..3e81bede9e1e72d16d1fa0760fa515c3f32c1f17 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=dummy98
 
index 8434c62efbe15fd26842146e0157be0583ddbeb5..472072b3fcae4a702e7f660ff1a2446b80752e21 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=dummy98
 
index ce2bbd8792e9ab9008b7ca577d8d1420505b47be..17ad558142b22cfdb3f72b482f07ad8318e72320 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=dummy98
 
index 7ad1e1b5b1fc79ec7744a22e02064cf210ffc536..a773210b7c2fde5be9a60220085a7f8d807b961a 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=dummy98
 
index c1ef30519c71b29f189dc83f6d5ce287fe62313c..f359329ff961b7c2d6fa9f26f96308001b96f0a9 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=dummy98
 
index e95e139391f02c5df7f8501e3c8f25924ab5c8db..b0afecdc2ba1854e9fbd11a3827461c801468af0 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=veth99
 
index a239619ec7bedc926b8c78200eda720581b3fdc9..7c3ae33ce7e6256e3a8f1771df3faa8bb6b922fe 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=veth99
 
index 609692f97aef29c34fe66ae8bf82271dce4724b9..b6724eaf5ea0dfc9779c42f19da66a780dae330e 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=veth99
 
index 4fe3c9a04b79b6a4f1d644ed6ac6a003dc1dee35..4b661fed478c68ce4797dd572e8e9391aa5426e5 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=veth-peer
 
index a06f100c34ee902d4cf684e831e8614b1533b0f2..9cf8f2575350666e289fefe4997051c672e61b06 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=veth-peer
 
index be0d2e40c56580067c4233dd535e605d83bceb6c..a8b7b0b54ef87fac36e6d9a82a269484df3c49f0 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=veth-peer
 
index 13fd0adeffeafd30a8d161e38ae7289ec3c3121f..14c239685ebd44261715cbbd8678d3b542aea9e0 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=veth99
 
index b046d9f992e203a88f8c9c6fbacb71e2fdc88939..a98f61efc352638fc3230f43c43c4b73bba55cd0 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=veth-peer
 
index d91847bde7d52ca12e6a792e8c3401ad4a565548..0afdda5a2e0bbc69e96c1e04ab3151a314eca331 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=veth99
 
index 9146def210542b471474c7dc97b432270d265ac1..78de566977abd3b5a86005409c82c85fa64d8308 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=dummy98
 
index b3fccb146f338c6acf3fa64ce983ec2061f3027b..c0c919b281c114fb1e20f909cc62ac03650cf25a 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=test1
 
index 4549164323163f8a5d498bb9e6824d4b8d463483..d66d98ad22f1bfe57c6a8ec80cf7b1ce4009f6fb 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=test1
 
index 9458330859ec4553a675a21848f0b45fa78d9d94..0f80426c80b5f8ac86cf80406443d17f701cb7ca 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=dummy98
 
index 5558547c28ae17ebf3172f2e5fe50be48aac31db..0066474556580fc6d7cf98ce72a809649018eec2 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=dummy98
 
index e18842ca23df3588d05a218f1074f1231a77cac1..d34d7bde1b6cc1ecce55ef187c30d005f5d2c410 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=test1
 
index 956d13fc3acc80409de757756f7249bd5fddb8b5..163c0de449bb64fb14cbec9e822b62ea74f9c243 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=test1
 
index ee18bea72e97d0955eac183c5073d8dff71d1207..8663e1ef669c93d78e6e2e3ee62273bdd7411f83 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=bareudp99
 Name=batadv99
index c75b8b45b9e44e38e2887451d36386e146290129..7cfc56c740dd7cc8d1fbeaf64f399f6366549b18 100644 (file)
@@ -1,2 +1,3 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Network]
 ManageForeignRoutes=no
index 804597cec45de218dc1bdd23cfa1224227a6f11d..d4c579f39cea95c1c3f0623fcf2264a29985d717 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=dummy98
 
index 96650c2551c77deb9c400da39712027e8a362a2c..d0c05c5dbdef862233f3da144e9c497b66e1dc35 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=test1
 
index d12fe0402093620404c76f304490acb60812ff0f..47bf4bba480fe7b5c57e80e435385bda0c446532 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=test1
 
index 2afd3277c47ea55bf5f932d71d646f9ca04cbee9..7d6e17cf6c0f963bb569da4f4523a5a1ec3b9550 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=test1
 
index 571c5c93d920f32e87785a0422ef24fe3efeb2ee..e05bf828e6c773062aeeb142cfa7d55f63fd5d4e 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=dummy98
 
index d9db9a9ab96f8ae331b26c38b06694e857ed280f..d321d60fed8fd584441093caa2780ca715f0aeca 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=dummy98
 
index 310be91fa52fa076cc886eb514f952ff9282c037..b2e5a18cb38a394b8f63d96a83bfaff81518937c 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [NetDev]
 Name=vlan6
 Kind=vlan
index 64e9db520e52aea19a05d50a0bfe8fb37159747f..417497208112606a6cb94c1eec6bc5cc45b89a7f 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=vlan6
 
index 888e79a79db9c7a2e2a46cc7f484ded071597c46..af80aadd04bd64bc448b04ff75be35d5d7e73772 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=dummy98
 
index 0916de86dd1f6f24b980c96539b4051dfcd86f52..2f73a995dd207d70699e5f3ed9f22c649fc0e531 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=dummy98
 
index 8ecff085c0b9a20e6e61288f343c77f2c7029799..fd22387143fdad9166fb3e968313f1ec5ec1e1c5 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=vxlan97
 
index d76be59dd12c2de39b29a93b4caa2e4bc71b16b5..4e9501c3b302b8044dfea44be655620a8deff682 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=test1
 
index 8222d2ba458a4f9576329a09a54a30a81424e1b1..683291f767bc293f223efa06106140a870a1aa6e 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=vxlan99
 
index bfb2956ae9d41fd47acdaa96f80557e9d0c373df..c852601733567759496c66771dcfc7526d92bb62 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Match]
 Name=dummy98
 
index 95d526a7f71b9061af24648e92946a0b2f0eb9c3..27ccc3ce23be2260f4b8c16ad5ffea9adf395dbf 100755 (executable)
@@ -4012,7 +4012,6 @@ class NetworkdDHCPClientTests(unittest.TestCase, Utilities):
         'dhcp-client-ipv4-only.network',
         'dhcp-client-ipv4-use-routes-use-gateway.network',
         'dhcp-client-ipv6-only.network',
-        'dhcp-client-ipv6-rapid-commit.network',
         'dhcp-client-keep-configuration-dhcp-on-stop.network',
         'dhcp-client-keep-configuration-dhcp.network',
         'dhcp-client-listen-port.network',
@@ -4193,8 +4192,7 @@ class NetworkdDHCPClientTests(unittest.TestCase, Utilities):
             self.assertNotRegex(output, r'9.9.9.9 via 192.168.5.[0-9]* proto dhcp src 192.168.5.[0-9]* metric 1024')
 
     def test_dhcp_client_ipv4_ipv6(self):
-        copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-server-veth-peer.network', 'dhcp-client-ipv6-only.network',
-                                        'dhcp-client-ipv4-only.network')
+        copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-server-veth-peer.network', 'dhcp-client-ipv4-only.network')
         start_networkd()
         self.wait_online(['veth-peer:carrier'])
         start_dnsmasq()
@@ -4247,30 +4245,6 @@ class NetworkdDHCPClientTests(unittest.TestCase, Utilities):
         self.assertTrue(search_words_in_dnsmasq_log('client provides name: test-hostname'))
         self.assertTrue(search_words_in_dnsmasq_log('26:mtu'))
 
-    def test_dhcp6_client_settings_rapidcommit_true(self):
-        copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-server-veth-peer.network', 'dhcp-client-ipv6-only.network')
-        start_networkd()
-        self.wait_online(['veth-peer:carrier'])
-        start_dnsmasq()
-        self.wait_online(['veth99:routable', 'veth-peer:routable'])
-
-        output = check_output('ip address show dev veth99')
-        print(output)
-        self.assertRegex(output, '12:34:56:78:9a:bc')
-        self.assertTrue(search_words_in_dnsmasq_log('14:rapid-commit', True))
-
-    def test_dhcp6_client_settings_rapidcommit_false(self):
-        copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-server-veth-peer.network', 'dhcp-client-ipv6-rapid-commit.network')
-        start_networkd()
-        self.wait_online(['veth-peer:carrier'])
-        start_dnsmasq()
-        self.wait_online(['veth99:routable', 'veth-peer:routable'])
-
-        output = check_output('ip address show dev veth99')
-        print(output)
-        self.assertRegex(output, '12:34:56:78:9a:bc')
-        self.assertFalse(search_words_in_dnsmasq_log('14:rapid-commit', True))
-
     def test_dhcp_client_settings_anonymize(self):
         copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-server-veth-peer.network', 'dhcp-client-anonymize.network')
         start_networkd()
index 8ffd8d78891f6f6ea6b436ca547abf34651cdff0..d13b36376ea1a96620e701390db245d8a9a99caf 100755 (executable)
@@ -1,4 +1,5 @@
 #!/bin/sh
+# SPDX-License-Identifier: LGPL-2.1-or-later
 
 echo "$0 $*"
 test "$(basename "$0")" = "script.sh" || exit 1
index d8cdd5ac14dc7748199d691bc01422007df889b7..45f71aac981f9712dbb621731f41e69a08e43e66 100644 (file)
@@ -1,11 +1,4 @@
-#  SPDX-License-Identifier: LGPL-2.1-or-later
-#
-#  This file is part of systemd.
-#
-#  systemd is free software; you can redistribute it and/or modify it
-#  under the terms of the GNU Lesser General Public License as published by
-#  the Free Software Foundation; either version 2.1 of the License, or
-#  (at your option) any later version.
+# SPDX-License-Identifier: LGPL-2.1-or-later
 
 [Unit]
 Description=Basic System
index e58bdd925f610c99d28fd9e20eb6b08777ea80d0..fbdd8f6259a86417e39619829e871996e0057e82 100644 (file)
@@ -1,3 +1,5 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
+
 [Unit]
 Description=Test PathChanged
 
index 1246ec2ee73273b2fd38fe89d0fccbf13564a8fe..c7e6b487d560b39bcebdc67491decc9fa4384cd9 100644 (file)
@@ -1,3 +1,5 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
+
 [Unit]
 Description=Service Test for Path units
 
index 17e599fc0e9be7f7e76bf5123d37b3239a0130e4..cce0899981adbf395386fac3ee68d488bc388649 100644 (file)
@@ -1,3 +1,5 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
+
 [Unit]
 Description=Test DirectoryNotEmpty
 
index 1246ec2ee73273b2fd38fe89d0fccbf13564a8fe..c7e6b487d560b39bcebdc67491decc9fa4384cd9 100644 (file)
@@ -1,3 +1,5 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
+
 [Unit]
 Description=Service Test for Path units
 
index c4c9105af44e7336d1063e73d123b2c2730be7ac..b18bbc893adda2b77d6400bce5d4304eb5b1066a 100644 (file)
@@ -1,3 +1,5 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
+
 [Unit]
 Description=Test PathExists
 
index 1246ec2ee73273b2fd38fe89d0fccbf13564a8fe..c7e6b487d560b39bcebdc67491decc9fa4384cd9 100644 (file)
@@ -1,3 +1,5 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
+
 [Unit]
 Description=Service Test for Path units
 
index a05859960546098c17c854131e3c70573bd8bb8d..7c0d89746df743dd55ae5f081fb1a6876a543b04 100644 (file)
@@ -1,3 +1,5 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
+
 [Unit]
 Description=Test PathExistsGlob
 
index 1246ec2ee73273b2fd38fe89d0fccbf13564a8fe..c7e6b487d560b39bcebdc67491decc9fa4384cd9 100644 (file)
@@ -1,3 +1,5 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
+
 [Unit]
 Description=Service Test for Path units
 
index 9408479c0f10898402f6994d251d4b8b58662977..24ff187fff119b23f862579704f46e00b81e0cde 100644 (file)
@@ -1,3 +1,5 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
+
 [Unit]
 Description=Test MakeDirectory & DirectoryMode
 
index 1246ec2ee73273b2fd38fe89d0fccbf13564a8fe..c7e6b487d560b39bcebdc67491decc9fa4384cd9 100644 (file)
@@ -1,3 +1,5 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
+
 [Unit]
 Description=Service Test for Path units
 
index 18363227bae12dfad985c9d6cf98d6ec3af4fc12..20207fb62a21803e4a4777406fe63c6d7c1f623a 100644 (file)
@@ -1,3 +1,5 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
+
 [Unit]
 Description=Test PathModified
 
index 1246ec2ee73273b2fd38fe89d0fccbf13564a8fe..c7e6b487d560b39bcebdc67491decc9fa4384cd9 100644 (file)
@@ -1,3 +1,5 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
+
 [Unit]
 Description=Service Test for Path units
 
index 6a9bac09cdc274cd2a1ad7d92adcf5ed3793ab71..b3924fe5ac7cc5c2f5d712e503c91fae2b218b83 100644 (file)
@@ -1,3 +1,5 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
+
 [Unit]
 Description=Service Test Path Unit
 
index 95e572d6d56ae2b31bcdb6e5d94939cbb9168a59..c79fa8ede4cd19b51bdfbc1a077890188d4e514e 100644 (file)
@@ -1,3 +1,5 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
+
 [Unit]
 Description=Test Path Unit=
 
index 1bec148bee8a794be1eedec909a29484d4052fd6..e2549a7a5b6990a1e70ab5d5e725d4f275ef50b8 100644 (file)
@@ -1,11 +1,4 @@
-#  SPDX-License-Identifier: LGPL-2.1-or-later
-#
-#  This file is part of systemd.
-#
-#  systemd is free software; you can redistribute it and/or modify it
-#  under the terms of the GNU Lesser General Public License as published by
-#  the Free Software Foundation; either version 2.1 of the License, or
-#  (at your option) any later version.
+# SPDX-License-Identifier: LGPL-2.1-or-later
 
 [Unit]
 Description=Paths
index eed3d16b458519b1ef6ecc99d24d4795538dc1b9..566f7b9776182b94b0ce1c2eb74ef876ecd1fd1d 100644 (file)
@@ -1,11 +1,4 @@
-#  SPDX-License-Identifier: LGPL-2.1-or-later
-#
-#  This file is part of systemd.
-#
-#  systemd is free software; you can redistribute it and/or modify it
-#  under the terms of the GNU Lesser General Public License as published by
-#  the Free Software Foundation; either version 2.1 of the License, or
-#  (at your option) any later version.
+# SPDX-License-Identifier: LGPL-2.1-or-later
 
 [Unit]
 Description=System Initialization
diff --git a/test/test-resolve/.gitattributes b/test/test-resolve/.gitattributes
new file mode 100644 (file)
index 0000000..6bebb3e
--- /dev/null
@@ -0,0 +1 @@
+/*.pkts  binary generated
diff --git a/test/test-sysusers/.gitattributes b/test/test-sysusers/.gitattributes
new file mode 100644 (file)
index 0000000..f03f6c0
--- /dev/null
@@ -0,0 +1,2 @@
+/*.initial*   generated
+/*.expected*  generated
index 297bbe350360575c8c88510ec09fcf76c01843f5..05c51e8532a5b6cd8e38c1c6f898e0af6bffb640 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 # Trivial smoke test that covers the most basic functionality
 #
 #Type Name ID  GECOS HOMEDIR
index 8e18a00a63691a8d4c41eeea658e5fa868a3c9d3..f5ae0873cd577e792ac1991929b375e9965fd0f1 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 # check that 'm' lines do not conflicts 'u' line
 #
 #Type Name ID  GECOS HOMEDIR
index bffc2cd7eae06925770c52cf9c2fbb9148a40cad..d881b7b5ce8027029881bde23e94fcba8cb1e11b 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 #Type Name ID  GECOS HOMEDIR
 u     u1   222 -     -
 g     g1   111 -     -
index 2913120276d9dc9bd4cef5697ae09da428c3e2a7..2dd2e4b44a1ac8a7962b793c5cc230509254551b 100644 (file)
@@ -1 +1,2 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 u systemd-coredump  1 "systemd Core Dumper"
index bad2f095050d35329b5f6a31fee6c366201a7a48..f2ccd44cc9dd32e16ab7489f983f1a4180749609 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 # Ensure that the semantic for the uid:groupname syntax is correct
 #
 #Type Name ID  GECOS HOMEDIR
index 0a11a2e325f63f739f15f2c26f623189160456b6..a1cf58bad0ea54b450b884795dddfb20697deb5f 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 # Ensure that a preexisting system group can be used as primary
 #
 #Type Name ID  GECOS HOMEDIR
index 773d9e5da1268b304331ebb75c85fb3eff7f2381..8d2b1aa83f7085a899f4a20d6229ab42849eaf41 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 # Test generation of ID dynamically based on SYSTEM_UGID_MAX and
 # replacement of all fields up to the login shell.
 #
index 3257082ceef5fc6854f669b30ceed6562a5bb79f..b4369597b9416a11b3d9decddbb1d010e094a5a8 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 # Ensure that the semantic for the uid:gid syntax is correct
 #
 #Type Name ID  GECOS HOMEDIR
index 557f61c42bdbc14ba3efba7477e0cdea2afda2a4..85275cb497ff481ddf6338e6d6ed9ef5076b496e 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 # Ensure that already created groups are used when using the uid:gid syntax
 #
 #Type Name ID  GECOS HOMEDIR
index 57519d7c9de4aead7b8c24896a65bbff6183dcd6..ac005d288436ca2617613cdd26dcce26e5aa298b 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 # Reproduce the base-passwd master.{passwd,group} from Debian
 #
 #Type  Name        ID GECOS Home directory
index 764f57e82506f829fd0dc07f85be3bbdd7e730de..f0b2c9c8d0686cc57cccefc641c646a7ddfc97ed 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 # Ensure that existing IDs are not reused by default. I.e. the existing
 # ID 111 from g1 will cause u1 to get a new and different ID (999 on most
 # systems).
index 4e10b74227e860d19b42f185c27574eaf762b0d0..a7f1e57803d65609f176eb66789fcaaa29f6ae3f 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 # Issue #8315
 #
 #Type Name ID  GECOS HOMEDIR
index b76dd3e20ce1a24ddcccc3ba29d786567891c616..055e899bd5999f8c979731ce8eae39134a1c286b 100644 (file)
@@ -1,2 +1,3 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 g groupname 300
 u username -:300
index 4d536472c28a3459c1feafb139d17563afb8aea8..dd31ff1c3a69e407bd9ec63d327b8b25d860888a 100644 (file)
@@ -1,2 +1,3 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 u user1 300
 u user2 -:300
index b8ed85525b38a779eb9141cb9762fec9584ef509..178382b002a631200f9ed339150f6c9e11595819 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 # Ensure invalid uids are detected
 #
 #Type Name ID  GECOS HOMEDIR
index 3266b2229b5bfb61459733e755924fb68bc30153..8d527464a91e7efa36850e5654a90053c09ff8e2 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 # Ensure it is not allowed to create groups implicitly in the uid:gid syntax
 #
 #Type Name ID  GECOS HOMEDIR
index 64e60dd606a02cffb5bd8cee20db269ad56a2d5e..cd4de7e2e6212613ab2d87a56fbff6e6aab3f046 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 # Ensure it is not allowed to create groups implicitly in the uid:groupname syntax
 #
 #Type Name ID  GECOS HOMEDIR
diff --git a/test/test-umount/.gitattributes b/test/test-umount/.gitattributes
new file mode 100644 (file)
index 0000000..6df434f
--- /dev/null
@@ -0,0 +1 @@
+*  generated
index 278145285c1caa703e31947e06322ffa469ca70a..c86b1315198fb0b7e14468d02d7e6b17c4fd4887 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=ForeverPrintHola service
 
index a9f713701ca57c2269e7710763fcb26ab5e10564..3d83f87fe07c346659f2d14cbc5b3dc565504f5c 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Silent successful service
 
index 5dc633206a1843e39f00163bb02c9b526c3962b8..94f9b47b722ddb21ee14947d5723fef4d367b460 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Service]
 Type=oneshot
 ExecStart=/bin/echo Start Hola
index 335f38c5b446bc6c427550b91e35d1fdbebf7311..3a22c15b25e9dfc48d7c361e94d6c98b652a0836 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Load systemd-test module
 DefaultDependencies=no
index af4e21975947f2c40d2b94013a2eeea9d3d17a85..50750fec915f5fae02f27dea75680440d04b9be3 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Before=local-fs.target
 
index 398d6127495b178a16afc92f00ee8dfb950cfece..c7fdf2f68e0ce717751ea7a8f9c9e917dfa18482 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 DefaultDependencies=no
 Conflicts=shutdown.target
index 2fb476b986d82fa7b154083116736825877890c4..fc8fad932790b9544731df85f60301336f1529a0 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Requires=test10.socket
 ConditionPathExistsGlob=/tmp/nonexistent
index 9cceebbb8e45d47f440f543d8634367f478b34e5..af1317b409d12ee6790970392cbaa6e82fe083a7 100644 (file)
@@ -1,2 +1,3 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Socket]
 ListenStream=/run/test.ctl
index 6832cb241c4eb283c30ea9bfe290783cc5bcb8df..b8695d844633f6337aba48a24ecd52a57a8141d8 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Fail on restart
 StartLimitIntervalSec=1m
index c7b262794598728b87f3af5c7a672544db03f8d0..45a18b93b5fda0dc152fa8c5d0b52d8125af13a9 100755 (executable)
@@ -1,4 +1,5 @@
 #!/usr/bin/env bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
 set -eux
 set -o pipefail
 
index baa655f2f1cf348e388e45116272dbdccaa2ac89..1d74963a30b6e11bd5eb472f794eaf124adbcbaa 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Testsuite: Fail Runtime (EXTEND_TIMEOUT_USEC Didn't occur in sufficient time after RuntimeSecMax.)
 
index 882900440f2d9d901ad626283762e6b7a8f6b730..38aebf2a8ff0435db3bdd74e31407c56927b092e 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Testsuite: Fail Start (EXTEND_TIMEOUT_USEC Didn't occur in sufficient time after TimeoutStartSec.)
 
index cdea2a9a2d0593aa0dee99198a35b514a29352d7..1910ac9ff445e6531640d4a5fe7f5fcad898a55f 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Testsuite: Fail Stop (EXTEND_TIMEOUT_USEC Didn't occur in sufficient time after TimeoutStopSec.)
 
index e2d7e607ba8c7f42c8b14a71129d6635dea01693..1fdc363f696da85d5f5e8d533eaf89c9f6b6a20a 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Testsuite: EXTEND_TIMEOUT_USEC Success - extend timeout on all services
 
index 15283b73a8c5ac6224c91b7187af8a3f5d7476eb..2f5744d15eca77b4190c74fb504b571bb300da9d 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Testsuite: Success Runtime (EXTEND_TIMEOUT_USEC > WATCHDOG_USEC however < RuntimeMaxSec)
 
index cfdcc33cc8c8e1adbd8a12aafb3027f98f22c13a..be518e9870326b34d0a60c63c1c394714e10682c 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Testsuite: Success Start (EXTEND_TIMEOUT_USEC > WATCHDOG_USEC however < TimeoutStartSec)
 
index c4600ace418d3052fad19a4941e8c7792310adec..2bd3e3e3ba3c6de238fb8e83356c8d532a16f80c 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Testsuite: Success Stop (EXTEND_TIMEOUT_USEC > WATCHDOG_USEC however < TimeoutStopSec)
 
index f9c6abb4937972fb0a3c0038a6b70bca31187abb..c39a8ba911c87ba392274458f30e9e986c62c3de 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Dependent service for percent-j specifier
 After=testsuite-28-pre.service
index 766a454d6a2e66aec54c5b61b23c385243067893..6067ba09acb96d72b80856b0f8a1f3f14cd3eba0 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Wants with percent-j specifier
 Wants=specifier-j-depends-%j.service
index 2b8ef989110b8d06aada470fe2b32ec06e98fcfe..0d77247cfdc54f9f876c315d3fae30bb8944cb50 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Service]
 ExecStart=rm -f /failed /testok
 Type=oneshot
index d5ed27cf6ba55ba5c870711c26d331c878ab47f3..e2e25d524ea4289688add99439edef922ff8e9e7 100644 (file)
@@ -1,2 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
+
 [Service]
 WatchdogSec=10min
index 3b6927c0d13ddd31587c265c4de602de8cbc8d16..abcf578402c9d9847b51d62c21cd955bf8335054 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Honor First Shutdown feature
 After=multi-user.target
index 17c1ec9686050449d990c554f07783a129a05d05..0cb574f3adb35fdf33530e9a070284f6f5f7d0ab 100755 (executable)
@@ -1,3 +1,5 @@
 #!/bin/bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
+
 echo "Honor first shutdown test script"
 sleep infinity;
index a6573bda0a91da97f45b6446ba21c9c522d465f3..3f31a1800077ba8e8ae4d6776218ce9bc64773e7 100644 (file)
@@ -1,2 +1,3 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Path]
 PathExists=/tmp/test63
index c83801874d46f3a8aa73ead7f24c0b265f97627e..0253943f0ccdfe13c8e1fee82c181b8c69ee75f4 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 ConditionPathExists=!/tmp/nonexistent
 
index db37ae71d40d2c31b4039fea67ff95ebb1ef4c33..3a7c9e11edf717ba6ba2491b461668e9700a605f 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=A conjugate
 Requires=a.service
index 4168d2d0513bbef615e6edb0ec184fe0bd388317..ec5d0594c3356d6b989e0fa2db9d3b7a472dece3 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=A
 Requires=b.service
index cb388493733b4e74f90563d8de54dddfe60cd3ce..1da1002cde800864408a5c660b9d4e0c1e77d442 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Relabel all filesystems
 DefaultDependencies=no
index e03bae36be79b15d3d0bd31a780aa3e02b318984..4503cf312898c495f0e9584b555f5b2d5d6863aa 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=B
 Wants=f.service
index e2f60a8fbf940f57088b4f43ad510391e5e7e051..a1ce28c82a56d9b23af963fb1aa693aaa88adb1d 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=C
 Requires=a.service
index 921fd2ee1b9b0b4e2793d836ad9cec673087b0f8..82023258e36ee48aa07aa810b242dc8f305280ea 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=D:Cyclic
 After=b.service
index c790b9d04bb7cb6a59494871a346f435b37fcfcd..385fbed4921390bf4b0db6332e38f7032750b171 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Daughter Service
 
index 75228f6470bc91be5859796061dc7430266491ea..720c1da00a44f2dee6f240a6fc5c9926df891ae5 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=DML discard empty service
 
index 591c99270c3a0abf8807e34609aefb9a69b4c248..93246ac0dbbb65e3c34ec2433ceaa3b406d40b85 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=DML discard set ml service
 
index e26d86846cad7f4c5e6b83cd867be08d3d801a3b..dc8a39747fa6d8169f277c94a68b7639bbda0db6 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=DML discard slice
 
index 142c98720cb87bdbd6c785690180eb3c71db8e1c..ac96de01cbbbf75ef549c712d3a06149d2d95b5f 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=DML override empty service
 
index feb6773e39db9e9ba93b46f1a08c2dce6f9a3c6e..ac664d1f6b87be571ddd1da64febdcbf8e04f89b 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=DML override slice
 
index 34832de4910ae9c755e187fb948a00fd0bef47ab..1e1ba3416e19af162d5f62334124fc2abd42bc83 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=DML passthrough empty service
 
index 5bdf4ed4b7bd7143d667f2af32224ea0b03acc41..9a1531125baead2f3d715164d6bfa52e4aa34bc5 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=DML passthrough set DML service
 
index 2e568b5deb157f3b01d2ab4357b83453a2cba2f5..65083bc24dd3907d0fc97089955c3d710bb4eff7 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=DML passthrough set ML service
 
index 1b1a848edb75ea0036900bc7235edc69a8f6b203..1c8769d2d8f2e49fb138ce46c8c8bea3ae49713b 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=DML passthrough slice
 
index 84e333ef045f418167128a9dd1f2a8a065768b02..8e00e7fbf66c0da6d40a996160db52cd39e1eccc 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=DML slice
 
index 5ba98c7c431e8897d19c76f0a51355e8495a2aaa..5bbcde26dd9ace354d736f47447aa4c240d36a1b 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=E:Cyclic
 After=b.service
index e7ed75ef0544e88e7c5df759e9c3d098e9ac4467..3626741258ae4e032dec24297623ce2246635199 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=End the test
 After=testsuite.target
index 7dde681c179f8fb2281cc593e91144975706d0e6..ca20053ee619767f4606692caf443e112d757363 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=F
 
index cbfa82a4545e44509a18ac32f8e44a69823ec43a..5fd794dfd1a98eb8caf3ba1e1de3e3b0625efd32 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=G
 Conflicts=e.service
index ab641300e4b1c99d581cf48668768d977d228ef3..4fe77b4a7db6ef75e55664394fbb0d6940c8118a 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Grandchild Service
 
index 74a7751cad4b28bcb7e5d30b561898be6dd9eab3..5361d42db7eab096fbcd25d767742c142ae2a5c8 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=H
 Wants=g.service
index 526fbd2a12e559dc825bd8be2ffa88ca18c85f77..b0ddb3031156e595aac483fcfcbc5c4aa3398107 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Sleep for a minute, then say hello.
 Wants=sleep.service hello.service
index 82907b64e14d701af09ab75d56021e9aff902f04..0c3f2f817d969e49a601bbbef0491471be24c628 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Hello World
 
index 938ea77bdf458695d38a40429322a9a6b96336a2..2b5e821638e632ccb510948a8720e17eaba3c86b 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=I
 Conflicts=a.service d.service
index 9eb645748e5eebf2eaaa0e82d35eea9b758b06c2..7fc0e4241ad6078781294148dcfc35f2c659f530 100644 (file)
@@ -1,2 +1,3 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Service]
 ExecStart=/bin/true
index 51b84b89ed4b1ac1adb2e33254bc3bc63416b08f..53d213c0e09d23edbba4a7ad16720ec76363f0b6 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 BindsTo=loopy2.service
 
index 9eb645748e5eebf2eaaa0e82d35eea9b758b06c2..7fc0e4241ad6078781294148dcfc35f2c659f530 100644 (file)
@@ -1,2 +1,3 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Service]
 ExecStart=/bin/true
index 606e26b5da7481529ed3aadd14d8510d67ad7859..b2af20ab41828730ce78d148acb88f82dd3aae75 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Service]
 ExecStart=/bin/true
 
index 606e26b5da7481529ed3aadd14d8510d67ad7859..b2af20ab41828730ce78d148acb88f82dd3aae75 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Service]
 ExecStart=/bin/true
 
index 9c5d208cb45d52c0707ca2a76c4ff0b7689a92a1..f4837da6cdab04805e213219d2a70938ec7b1f4c 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Nomem Parent Slice
 
index 3cbaccb82f1d6a314926e47317db9488d97fb947..14ce5ad326cf6fea0e351f9cf0f005cbefecc82c 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Nomem Leaf Service
 
index 79b302f38d3fd516de9eacdd2932d9333a7bd1ad..983ed65ffb3fd6db28bc4ad0ba5a66083c112ce5 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Deeper Parent Slice
 
index a95f90392dbc5779086a794d9bfba35a762a40e2..f49530b6fbce8e23713482e46f764954993687ff 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Parent Slice
 
index 589a87ccfdc0004f1e16c0ae6ab81a65bfbb9de6..be8f1c27c395cf42beded19bab4d8b2641a26a0c 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Bad sched priority for Idle
 
index 262ef3e319cb5536d9be5d60f21c19bd53b56150..5a1d809339b18c7faaac2576bc58168897061414 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Sched idle with prio 0
 
index 0be534a5467c4c3f78ae96a621ede0a250ff99c5..c112fdf7cccb9ec8b33ee023cc3c5b34a761b6d9 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Bad sched priority for RR
 
index b3e3a000f88438598a9f9995656325ab723881c6..dad7e9bbdf1f4f433add4fdddd73fc422bb7a156 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Change prio
 
index b88adc54343cb5ab804944a7e9ce7948c475f8d9..00b98220971e36f2da7eee1c7318f290a254abf7 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Default prio for RR
 
index 946c44b621012e9bfa5a36fbf1f8fe0215936b9e..32c2037a09433c493ed63c0085ccb5c39cf71e3d 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Sleep for 1 minute
 
index 50bb96a94150c3a2b69341e650b6f97621704a02..2059118f01e1dd9d0fffd6cc64e88d758bbfbced 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Son Service
 
index cdd6b3436224131b82f56e678b108135b27e83f8..1c81efc1b126a0ce9d2f83d56a92bd9b1fcf66d4 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=TEST-01-BASIC
 After=multi-user.target
index 075e979d2997151163491b427e788f002bf5fef5..dea2c4f501ab1c0a8c1dc75113b2c3253537b7f4 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=TEST-02-UNITTESTS
 
index b16e8547ab5b8b74001168e427b4e5a530001e84..af6e00782555bb02aa5b87c28fe96c1a940490a7 100755 (executable)
@@ -1,4 +1,5 @@
 #!/usr/bin/env bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
 set -eux
 set -o pipefail
 
index fe18fdc7d7c3eb359d40bf8ee9c4c85ffccacefe..836f9621de3daddf3da67f5c46d205f21df90ad9 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=TEST-03-JOBS
 After=multi-user.target
index 8a8ba870e8c4cb54da4b5560277a3cf50ce9a009..070e978cda11ed54eed0e10c08e8fac4fb0da7da 100755 (executable)
@@ -1,4 +1,5 @@
 #!/usr/bin/env bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
 set -eux
 set -o pipefail
 
index 3d2b4a8bc2b794038ab199f9f604853f7aa1588c..63a010417e0ddf59398953f05747de3c5d8e9a3d 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=TEST-04-JOURNAL
 
index 562f3647009161f0c5a78c59e91229f44975e73a..7521a6d2e5ae8d248b443a4c15267a900e40ee07 100755 (executable)
@@ -1,4 +1,5 @@
 #!/usr/bin/env bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
 set -eux
 set -o pipefail
 
index 66356fd16f2889fd1253717aaeee0816975d24ae..ab72d8fe27ad35f43c2ae9e35b9ddfc69dd300dc 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=TEST-05-RLIMITS
 
index c98d849b08aa0004be48ae3a37a7495f6a209c97..870845d14bf42cd3105f16451826010161dee803 100755 (executable)
@@ -1,4 +1,5 @@
 #!/usr/bin/env bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
 set -eux
 set -o pipefail
 
index 3f8dad36dc7402769c45d7d05578d5c6b34eeac3..b91f93ca09c40f20ed72650a6f32552f75a64c4a 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=TEST-06-SELINUX
 
index f89698ded4171e4ae1b0a45c12b028cce38ce73a..c57d8b9488861b60a56e5de4f8cb8534259b3bad 100755 (executable)
@@ -1,4 +1,5 @@
 #!/usr/bin/env bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
 set -eux
 set -o pipefail
 
index 2506c211c2bc65ea1883b1231dc867e47c3e5e2f..c478e123608aa8b386ddf8750bae60d34d09f47b 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=TEST-07-ISSUE-1981
 
index bd1da341acb67b8bf4cef915182d4e06982b0590..5e9fe64ea9f9fc87b9402b5834a3ad7edab93d21 100755 (executable)
@@ -1,4 +1,5 @@
 #!/usr/bin/env bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
 set -eux
 set -o pipefail
 
index d961dc7ae295d51300f94b97228462b5db8847f8..d6937663e2fb7d6d02fc49a9f8d90bf9d89cc9df 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=TEST-08-ISSUE-2730
 
index fc59e808893ddf87a6674a68fd9a58599ee2b382..6f6cd9c522775901753f146aa5296cd89b49f1e9 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=TEST-09-ISSUE-2691
 
index f81a9e3ace22b942bf66a099ce819cf2443c0586..94eeb20781228da312c835c4e24fa0b60fcd8396 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=TEST-10-ISSUE-2467
 
index 1544fd68198078bcc1026670c580135e59c5b4e6..5dfcf50e3f99aa236371447c44906b385f8d7887 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=TEST-11-ISSUE-3166
 
index d05f6098777dae20bc3c95420614dd64570a480b..7e1391d8eab00eaabfc11285aa9754d79386c4e5 100755 (executable)
@@ -1,4 +1,5 @@
 #!/usr/bin/env bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
 set -eux
 set -o pipefail
 
index 72894eff9297afac2edd3c83dc079bb8c9c79a6d..b26cfa575de0b44a5b93d30b42410db2e786ce27 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=TEST-12-ISSUE-3171
 After=multi-user.target
index c4ee600abe1c96f692e16c92ea66e0a7bbd405d5..e64f321273289e7c4e22f77cae1b4932b70278a6 100755 (executable)
@@ -1,4 +1,5 @@
 #!/usr/bin/env bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
 set -eux
 set -o pipefail
 
index 5086793a90aa0bd1a41e746b8d1a409d41a5ba9a..a964d8d0336f3347f6d4e1c752df405b0e5f881d 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=TEST-13-NSPAWN-SMOKE
 
index 3f5a542738634471aa6ef7bfcd9c86ba5f84cd7c..554d098ef56bbb4c28371c3852a5f7716f72348e 100755 (executable)
@@ -1,4 +1,5 @@
 #!/usr/bin/env bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
 # shellcheck disable=SC2016
 set -eux
 set -o pipefail
index 1606c68fb163529fbe2d562c10d475a27ef9f5ad..23644e53a7b4f3eb24f09c06d0ee87ef0f929d12 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=TEST-14-MACHINE-ID
 
index 7a64d937361916441c8c842be497e388ad5338d4..54275910cf52a225fff905f50df7e24d6d8fb8e9 100755 (executable)
@@ -1,4 +1,5 @@
 #!/usr/bin/env bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
 set -eux
 set -o pipefail
 
index 09571ed1abd08b5df1095fd123db9e7932c9568d..10af93f0f7d1285c630156b8287cf980bcf48f76 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=TEST-15-DROPIN
 
index c3784e299d5c8689bc8faa6d31a40075cebba8de..56ac1f774f89211603b200bb5a5a7e573222bc71 100755 (executable)
@@ -1,4 +1,5 @@
-#!/bin/bash
+#!/usr/bin/env bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
 set -eux
 set -o pipefail
 
index 34e89ff7527af75af70cc45fa250582b534284bb..d5494ae9310dad113591550274c74cf66ea33519 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=TEST-16-EXTEND-TIMEOUT
 # Testsuite: Assess all other testsuite-*.services worked as expected
index 9f3a843da612be21326379a36a74114352ac9b8c..1b8cd018bb110228e7993a21f7334c55bfc41bef 100755 (executable)
@@ -1,4 +1,5 @@
 #!/usr/bin/env bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
 set -eux
 set -o pipefail
 
index 4f9f72daf10738eb1511caa963523bebb0f43e16..44f36f59558a5bbf564fff4ed4abe853cdb5732e 100755 (executable)
@@ -1,4 +1,5 @@
 #!/usr/bin/env bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
 set -ex
 set -o pipefail
 
index b73bd977022f3f5a378d843386760356f8d33c45..797676fc14271e1f49e0d52fd803d32511c61d02 100755 (executable)
@@ -1,4 +1,5 @@
 #!/usr/bin/env bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
 set -ex
 set -o pipefail
 
index 93cbf146a1ab1c3531164328536318ca133f406c..fecfd17952fb88825a9897abdec3b5545d77339f 100755 (executable)
@@ -1,5 +1,5 @@
 #!/usr/bin/env bash
-
+# SPDX-License-Identifier: LGPL-2.1-or-later
 set -ex
 
 test_rule="/run/udev/rules.d/49-test.rules"
@@ -28,7 +28,7 @@ teardown() {
 run_test() {
     since="$(date +%T)"
 
-    udevadm trigger -w --action add /dev/null
+    SYSTEMD_LOG_LEVEL=debug udevadm trigger --verbose --settle --action add /dev/null
 
     for _ in {1..20}; do
         if coredumpctl --since "$since" --no-legend --no-pager | grep /bin/udevadm ; then
index be386ccf61e2682de3134643b383ad1bc00dab34..d1c3c8556672a5c9a0107616357d28f8c2962b16 100755 (executable)
@@ -1,4 +1,5 @@
 #!/bin/bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
 set -ex
 set -o pipefail
 
@@ -15,7 +16,7 @@ ACTION=="change", SUBSYSTEM=="mem", KERNEL=="null", TAG+="changed"
 EOF
 
 udevadm control --reload
-udevadm trigger --settle --action add /dev/null
+SYSTEMD_LOG_LEVEL=debug udevadm trigger --verbose --settle --action add /dev/null
 
 test -f /run/udev/tags/added/c1:3
 test ! -f /run/udev/tags/changed/c1:3
@@ -24,7 +25,7 @@ udevadm info /dev/null | grep -q 'E: CURRENT_TAGS=.*:added:.*'
 udevadm info /dev/null | grep -q 'E: TAGS=.*:changed:.*' && { echo 'unexpected TAGS='; exit 1; }
 udevadm info /dev/null | grep -q 'E: CURRENT_TAGS=.*:changed:.*' && { echo 'unexpected CURRENT_TAGS='; exit 1; }
 
-udevadm trigger --settle --action change /dev/null
+SYSTEMD_LOG_LEVEL=debug udevadm trigger --verbose --settle --action change /dev/null
 
 test -f /run/udev/tags/added/c1:3
 test -f /run/udev/tags/changed/c1:3
@@ -33,7 +34,7 @@ udevadm info /dev/null | grep -q 'E: CURRENT_TAGS=.*:added:.*' && { echo 'unexpe
 udevadm info /dev/null | grep -q 'E: TAGS=.*:changed:.*'
 udevadm info /dev/null | grep -q 'E: CURRENT_TAGS=.*:changed:.*'
 
-udevadm trigger --settle --action add /dev/null
+SYSTEMD_LOG_LEVEL=debug udevadm trigger --verbose --settle --action add /dev/null
 
 test -f /run/udev/tags/added/c1:3
 test -f /run/udev/tags/changed/c1:3
index 4bfc09a7cfa65ea36921e80d12abeb82ea464bb1..60be31a126ca3d64c523140aaf9ae2799977d1cd 100755 (executable)
@@ -1,4 +1,5 @@
 #!/bin/bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
 set -ex
 set -o pipefail
 
@@ -10,7 +11,7 @@ ACTION=="add", SUBSYSTEM=="mem", KERNEL=="null", IMPORT{program}="/bin/echo -e H
 EOF
 
 udevadm control --reload
-udevadm trigger --settle --action add /dev/null
+SYSTEMD_LOG_LEVEL=debug udevadm trigger --verbose --settle --action add /dev/null
 
 test -f /run/udev/data/c1:3
 udevadm info /dev/null | grep -q 'E: HOGE=aa\\x20\\x20\\x20bb'
index cd98ed82175d1862cd34d8b630e88a847921632e..f2a0442dc31ced64e9f3f8457fe7af80ce2e8c16 100755 (executable)
@@ -1,4 +1,5 @@
 #!/bin/bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
 set -ex
 set -o pipefail
 
index bd6221551c34b5cb7e262abcf342407bceca2e2d..d218d7266f0a10f6198734f1fc0a6c8315221127 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=TEST-17-UDEV
 
index 92ff7b56a6b5fe9a8aba913f407631ffd8f1ff81..b389875ef1ab551c67d34747c01f8d1865760880 100755 (executable)
@@ -1,5 +1,5 @@
 #!/usr/bin/env bash
-
+# SPDX-License-Identifier: LGPL-2.1-or-later
 set -eux
 set -o pipefail
 
index e4a945dc3ed29fa2ceaf8b045f6b4d3bf768155e..16d90a12c2e6a74a82eb8514e06dd1809508595b 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=TEST-18-FAILUREACTION
 
index fe4f9ce5e0eda055d8fb4f5519a2bb204dac2adc..e9d7c5bfc87f8477d85a745184c5ccfe441379a5 100755 (executable)
@@ -1,4 +1,5 @@
 #!/usr/bin/env bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
 set -eux
 set -o pipefail
 
index d6ad5bededaafe695681a330eb39efb9ad75ee92..9ee5fc97d2392341015be95c416714f200fb925b 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=TEST-19-DELEGATE
 
index 8ea89e6cfe8d5ef09f68c99cf9166813e9646aa7..ee4eb8431eef0ee74edc5946c00db03ab21968c3 100755 (executable)
@@ -1,4 +1,5 @@
 #!/usr/bin/env bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
 set -eux
 set -o pipefail
 
index d31d531175676560a39f62b6e885c774bb158b23..4228d0b875e2a0de81a6c3be3898addb93b7fd3b 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=TEST-20-MAINPIDGAMES
 Before=getty-pre.target
index 7876a9d10c3b4171076f164f48eb272e5ab2395f..17a27d7d7c8abeb254516907f3a0464e04905d67 100755 (executable)
@@ -1,4 +1,5 @@
 #!/usr/bin/env bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
 set -eux
 set -o pipefail
 
index 7975980799611bf3167f8810b8ae5631db0fa41b..2276b75d35573257f945c7e60a6a9889c5021e00 100755 (executable)
@@ -1,9 +1,8 @@
 #!/bin/bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
 #
 # With "e" don't attempt to set permissions when file doesn't exist, see
 # https://github.com/systemd/systemd/pull/6682.
-#
-
 set -eux
 set -o pipefail
 
index 94fa11ba8861e239a244a859b95ecd1218203b78..0719d68292ba2665f4a24c5b184d935d413acc32 100755 (executable)
@@ -1,8 +1,7 @@
 #!/bin/bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
 #
 # Basic tests for types creating directories
-#
-
 set -eux
 set -o pipefail
 
index 1ed026eb709d324edc8af53a209623603eaf350a..404e33e2fa8c148fbff7b854ac591a1a4f5e6118 100755 (executable)
@@ -1,8 +1,7 @@
 #!/bin/bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
 #
 # Basic tests for types creating/writing files
-#
-
 set -eux
 set -o pipefail
 
index d814ed87867308d1453a8fa33169be73a490beb2..7bf2b28edc08a715d423616254a713be101c97a1 100755 (executable)
@@ -1,8 +1,7 @@
 #!/bin/bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
 #
 # Basic tests for types creating fifos
-#
-
 set -eux
 set -o pipefail
 
index eaabbc4517c8e59ece250e9efcd370b81ac43378..cde9b5d61c7e2cbd0259b8f602444454c366a378 100755 (executable)
@@ -1,5 +1,5 @@
 #! /bin/bash
-
+# SPDX-License-Identifier: LGPL-2.1-or-later
 set -eux
 set -o pipefail
 
index ce5b1bf69813d0bdf1727d7ffbbe2654b884eb26..f64a95ce1ac467effc246e7fe9ec520fee16b74c 100755 (executable)
@@ -1,8 +1,7 @@
 #!/bin/bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
 #
 # Inspired by https://github.com/systemd/systemd/issues/9508
-#
-
 set -eux
 set -o pipefail
 
index 8d61032d277bf7d3866d3d69f4b59c7f152fb713..de20d5ee900e55cba171940d9664f93054ad7f82 100755 (executable)
@@ -1,8 +1,7 @@
 #!/bin/bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
 #
 # Verifies the issues described by https://github.com/systemd/systemd/issues/10191
-#
-
 set -eux
 set -o pipefail
 
index e4272f8ea3ae7e4de75f9deb088ff38088bb8316..65f1832adc815899ce7d9cd64bd7e51c98893093 100755 (executable)
@@ -1,12 +1,11 @@
 #!/bin/bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
 #
 # Verify tmpfiles can run in a root directory under a path prefix that contains
 # directories owned by unprivileged users, for example when a root file system
 # is mounted in a regular user's home directory.
 #
 # https://github.com/systemd/systemd/pull/11820
-#
-
 set -eux
 set -o pipefail
 
index c852f778efaa1e8dc8982a58a9f5924f66d17fc2..0857773526eeb16033f1b35744241931d23c6a39 100755 (executable)
@@ -1,5 +1,5 @@
 #!/usr/bin/env bash
-
+# SPDX-License-Identifier: LGPL-2.1-or-later
 set -eux
 set -o pipefail
 
index d650b2145c20b61342a5fc3831bb4554a4eed08d..99052c808f256004063c38e0e3fe49866c533a36 100755 (executable)
@@ -1,5 +1,5 @@
 #!/usr/bin/env bash
-
+# SPDX-License-Identifier: LGPL-2.1-or-later
 set -eux
 set -o pipefail
 
index 21ef210cd1658315111b425d9b7df6e9fa471953..f71a95f4f394f1983a63a9a7b87977b7bca3c643 100755 (executable)
@@ -1,5 +1,5 @@
-#! /bin/bash
-
+#!/usr/bin/env bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
 set -e
 set -x
 
index 7f27b40acd7c04f50bbfcc5d44b776e27f7dbbb6..b8c4da8381cda74d239fef23015d6072c8c8dcd8 100755 (executable)
@@ -1,7 +1,7 @@
-#! /bin/bash
-
+#!/usr/bin/env bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
+#
 # Test the "Age" parameter (with age-by) for systemd-tmpfiles.
-
 set -e
 set -x
 
index 55e3056d53cebb42ba1c086ef5aa62e8347a03fa..b9ecc4c5d63066e016a6e3bf1dc6bdab05a9a5ae 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=TEST-22-TMPFILES
 After=systemd-tmpfiles-setup.service
index 65d08029690420d70440997124df781255dbaa8e..43823f1d466fd85663d760b9eb6d0a3dabbfeffd 100755 (executable)
@@ -1,5 +1,5 @@
 #!/usr/bin/env bash
-
+# SPDX-License-Identifier: LGPL-2.1-or-later
 set -eux
 set -o pipefail
 
index b3b3297af8c8b32793509afdd66f32e8da8ded04..26f5226cd4d9c409e89590c8d5d7becbcd203057 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=TEST-23-TYPE-EXEC
 
index 5488447a87653a4de8b3ecec7035e05701830b68..46e45c8780d6b9eebf144d0500dd5b5a426f4d3b 100755 (executable)
@@ -1,4 +1,5 @@
 #!/usr/bin/env bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
 set -eux
 set -o pipefail
 
index e66f61388f11e42a30a436253ca9d98e64e01768..ccae834371def7228ffe7bed53cb2c75359cc589 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=TEST-24-CRYPTSETUP
 After=multi-user.target
index 45d8b6945f4b7407a703e69513c47cef3fc74520..503eabbe07962a20a7344ce364088ab2ba1534e6 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=TEST-25-IMPORT
 
index fbe2d0b1d4d9965906ffed22b68862a3d78ff0f6..4119d777b37a5e7b0f3bb8681f074060cb8968a3 100755 (executable)
@@ -1,4 +1,5 @@
 #!/usr/bin/env bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
 set -eux
 set -o pipefail
 
index 65b66835ed3c865b579e1a235bde91eff78715ab..aa553b61a6626979dfe7239e76db4686adaef6ab 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=TEST-26-SETENV
 
index 79820993074eccbe6cf118640479c0e748c2e8e6..7df0d1dc8f3bfab4ff4c37c888f0c9f8a44733e7 100755 (executable)
@@ -1,4 +1,5 @@
 #!/usr/bin/env bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
 set -eux
 set -o pipefail
 
index 52185f0572591724936420f8d648cdda715766cc..454fde6108917e5cb257f7824c6486d2c626268c 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=TEST-27-STDOUTFILE
 
index 2248380351a7a99ad88ddb59264c3972718207b7..3b2f9251539f313a60bc8d3adeb794147c592e23 100755 (executable)
@@ -1,4 +1,5 @@
 #!/usr/bin/env bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
 set -eux
 set -o pipefail
 
index 7ea863001189ff041b5496d4bf208afe252c2c63..222de00c32f6868b9f690dfa690a636bfdfa6841 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=TEST-28-PERCENTJ-WANTEDBY
 # Testsuite: Ensure %j Wants directives work
index 900b99f77b96db76f55775a1a8cadbbfe83f790a..035c6bf4ef4a76db645252bd5d06bd90f4c8a894 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=TEST-29-PORTABLE
 
index 7775695e6dfe2a090b288366df6e81269d639fda..11f1832aa417b38992de0bd027b8ad48545d4126 100755 (executable)
@@ -1,4 +1,5 @@
 #!/usr/bin/env bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
 # -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*-
 # ex: ts=8 sw=4 sts=4 et filetype=sh
 set -eux
index eb342f3d17e70b9484189d895343b774fcf2a940..253f7b51d407a1ae07b3e41ae442c3d898614c86 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=TEST-30-ONCLOCKCHANGE
 
index ac8a3e06cf561863847e9f843f1ba318e277487b..51b9bdd09311b7ec6609a7c473ff9129f76646ae 100755 (executable)
@@ -1,4 +1,5 @@
 #!/usr/bin/env bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
 set -eux
 set -o pipefail
 
index 07dfb0bb5429916288150cea45a952a9e8972531..f0e78a9d0104d4e46e1e3d186018b831e2bde5a0 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=TEST-31-DEVICE-ENUMERATION
 
index a9a50e1470b02a6764b1d6c1ccb79e284c1f3858..024ad3652fb88e42710cf8d3efe5c577c1549405 100755 (executable)
@@ -1,4 +1,5 @@
 #!/usr/bin/env bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
 set -eux
 set -o pipefail
 
index aab95cb7419363c0158e8be416cd739ca169bc3c..50f5823d31768d51eaca845380005afa0c0c1d4a 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=TEST-32-OOMPOLICY
 
index 2393601a007ff8932895d83351aa21b6a652483e..20ab67f6f111cb9c063dd58e1e66f0cd8e1ad2c4 100755 (executable)
@@ -1,4 +1,5 @@
 #!/usr/bin/env bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
 set -eux
 set -o pipefail
 
index b64f1e0b79e55fcc89dce962c84602631288b80e..582cdb180c4846378c4103a45acb80a507cc7737 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=TEST-33-CLEAN-UNIT
 
index 6e750f63a3817a2f1b2a70cf817ecf4bfaaabd5a..b951eef88b7bf95f6e5a17d9634f37abf0138b16 100755 (executable)
@@ -1,4 +1,5 @@
 #!/usr/bin/env bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
 # -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*-
 # ex: ts=8 sw=4 sts=4 et filetype=sh
 set -eux
index 361e328221ccd035117acf8f2438f988c7a3aef5..6917afe448650f420ae163828c93609dc9164b15 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=TEST-34-DYNAMICUSERMIGRATE
 
index 394b220d60a31f02d5b4b6f6b9b1d9d6cd6c6a9c..97244ac4571f2edd535f479e87cc05ea9ab394ae 100755 (executable)
@@ -1,4 +1,5 @@
 #!/usr/bin/env bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
 set -eux
 set -o pipefail
 
index a681153ee455723ea64c8faf15b414df978aa000..5746dc1ca840fdd6c2b033e24db8782fdbaae2aa 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=TEST-36-NUMAPOLICY
 
index b684011785feeab1df629c5b9723208096786aef..b6c00c4845e0187fa0450db3819f5669e8d9d75b 100755 (executable)
@@ -1,4 +1,5 @@
 #!/usr/bin/env bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
 set -eux
 set -o pipefail
 
index d25c6d2cf9b5e6c4c29e0afe40ae93caa9513e73..ccad5e2d31a568ba219093427d3cf4aa3f74872b 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=TEST-37-RUNTIMEDIRECTORYPRESERVE
 
index c3eb5344d1163808005b2bf46de9d1c1d8e261c7..1aec383c0c4ecf050bda7d370ed62e974d55706a 100755 (executable)
@@ -1,4 +1,5 @@
 #!/usr/bin/env bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
 # -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*-
 # ex: ts=8 sw=4 sts=4 et filetype=sh
 set -eux
index 859f97b3601561bb56e6cdabdef8519d40f5f5f4..c116c80981b4793f1ff9b5fcb3fb53e0fc9a5a15 100644 (file)
@@ -1,2 +1,3 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Service]
 ExecStart=/bin/sleep 3600
index c848840ba0c12acb784257c31e3d594a0cf4f98d..ac77836986989999bc71b73a7ac89e03479fb6af 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=TEST-38-FREEZER
 
index e58bae81fec23d461c3b3c55134483f452bac773..f2f61b961f5239b97050b27d9c2b45efa2a23643 100755 (executable)
@@ -1,4 +1,5 @@
 #!/usr/bin/env bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
 
 set -eux
 set -o pipefail
index 395fe803e7722e1b637d2eecddb629f10fd109ba..1567dfaa08c34fb51cf6f5a3ac05fa0d7d9408a2 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=TEST-39-EXECRELOAD
 
index 3b0d893a4c0bc9b779bf778ea83504e3bbb4d119..03abf391f1d007e57921e28f53e76460edcd52e0 100755 (executable)
@@ -1,5 +1,5 @@
 #!/usr/bin/env bash
-
+# SPDX-License-Identifier: LGPL-2.1-or-later
 set -eux
 set -o pipefail
 
index 38b0bd80d13f4e4fd0cacd1223e791b82f7f38e9..eec4ddc99a2fe59e4b25dc25a704328854cfbfb5 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=TEST-40-EXEC-COMMAND-EX
 
index fdb052c39ca7a48ba121fea5fd5ac73d58fb2423..dd54fa174cee3c354d02063bf56f60a2499c8c1f 100755 (executable)
@@ -1,4 +1,5 @@
 #!/usr/bin/env bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
 set -eux
 set -o pipefail
 
index 766cb4c99af80934db07d6d4926faa4208b2af48..bbd8a72d7ccaa2ce4e0e34c35aa4174d003c0753 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=TEST-41-ONESHOT-RESTART
 
index e7993e8df789eff1e88197cb402c2d97125b5670..3b41db03f58d59975dce6d72468bee7df824b7e2 100755 (executable)
@@ -1,4 +1,5 @@
 #!/usr/bin/env bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
 set -eux
 set -o pipefail
 
index a5504b515d7ee2aa98b3a007dafddff905058e4a..f57e616466cf3a5f8532a0935627db342f6085e1 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=TEST-42-EXECSTOPPOST
 Before=getty-pre.target
index 4e6be7e06eb49c58fd804ca214e15f962470e6e5..9476df86dde9037629570ba4156db4fa9698e2d0 100755 (executable)
@@ -1,4 +1,5 @@
 #!/usr/bin/env bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
 set -eux
 
 systemd-analyze log-level debug
index 31248f17e8acadeb68502642dc3003fa0b91e720..e36afea4186c2a64f3ac512d005e18e902e0cd25 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=TEST-43-PRIVATEUSER-UNPRIV
 After=systemd-logind.service user@4711.service
index c6399f9920bb1882b20aa67992cbe1daf7325c75..9c0f93b518517397b09af49e4f8363ee87454d6c 100755 (executable)
@@ -1,4 +1,5 @@
 #!/usr/bin/env bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
 set -eux
 set -o pipefail
 
index bd4dd728aa633c699dc46416b60ae13b6cee2ca6..e0d4a8c18d0711d6050ea3308f4db41cc4454b70 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=TESTSUITE-44-LOG-NAMESPACE
 Before=getty-pre.target
index 0100b31b576978534ae20d3155e58bd7bb683b5f..49c240ff8e45b43026b8a061879f8cf9055b2821 100755 (executable)
@@ -1,4 +1,5 @@
 #!/usr/bin/env bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
 set -eux
 
 systemd-analyze log-level debug
index 7698f35979d9a60cbbc4a6383d94520ded35adab..26b3350b51508757b72298fa17aa093ee13831ba 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=TEST-46-HOMED
 Wants=getty-pre.target
index 808270f33d917dbe99b1a24d1a307f0d107269ce..72d1fd6f8506c870d284265e30dc99a466da1014 100755 (executable)
@@ -1,4 +1,5 @@
 #!/usr/bin/env bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
 set -eux
 set -o pipefail
 
index 655eea68e55da262d14a61620506ed50b9710980..1508ac624243c643cd4d2f00e62e5a80181ced42 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Issue 14566 Repro
 
index b008f52e9521e33cd2c8988b026efa298e240fcd..74fa7605e7a220d5678600370878f3e89cc60102 100755 (executable)
@@ -1,4 +1,5 @@
 #!/usr/bin/env bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
 
 sleep infinity &
 echo $! >/leakedtestpid
index 3816c57eed61b646b2f6eccc26d614aacc1d706b..d5ad4801085ccd335ec4f0afc2fc056ed686312f 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=TEST-47-ISSUE-14566
 
index c1714d14d0e39a9b91291a0bae801f1ac9e2b5dd..ff10602df79295ef315b32a065de19434aa04a2d 100755 (executable)
@@ -1,4 +1,5 @@
 #!/usr/bin/env bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
 set -eux
 set -o pipefail
 
index 9dc50ab15cde9df6f69d71582ebca7a4e38a6da5..74769563e31c39a224dbef5250b2a103d1862e01 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=TEST-48-START-STOP-NO-RELOAD
 
index 147f6fa54fa8669da3aca629bf4bbbefe8c01ea2..2b5b86f6e8ba6cd27daccbbe99e944ed18d06545 100755 (executable)
@@ -1,4 +1,5 @@
 #!/usr/bin/env bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
 # -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*-
 # ex: ts=8 sw=4 sts=4 et filetype=sh
 set -eux
index 722dbe246d688283f93179a96b08455ca5411452..93abc31cdc36bb67be931f16c8534db034853946 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Service]
 RuntimeMaxSec=300
 # Adding a new mounts at runtime works if the unit is in the active state,
index e86c64d12542ebfc034b09e333db64aa8ec52438..db4e8d975fd703ab5a087a4f8f7f771deb047799 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Service]
 RuntimeMaxSec=10
 Type=notify
index 9475109ca2cc5b6c8bc92fb10a1057913a66f888..bd4e15558f9d6602ec1d315fcc136e64d7f0a6e6 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=TEST-49-RUNTIME-BIND-PATHS
 
index 8e360b4951c4900ef0b28f2e2fdcbdebd9d0ae3b..1fa972552b3e695332154e3f0623440915195976 100755 (executable)
@@ -1,4 +1,5 @@
 #!/usr/bin/env bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
 set -eux
 
 echo "MARKER_FIXED" >/run/testservice-49-fixed
index 5a10a6418b2187347f94de3f60b5746e4f0ea129..bcafe6e0ba7411f20c7d3cc67ed9398d16cd0a25 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=TEST-50-DISSECT
 
index a8024b32e3beea288ce3b6bdd91fc0bad3e1d305..e7e4e4b147b795d68c43f811fffbd4290578036c 100755 (executable)
@@ -1,4 +1,5 @@
 #!/usr/bin/env bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
 # -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*-
 # ex: ts=8 sw=4 sts=4 et filetype=sh
 set -eux
index 96ecabe23472e6cde2ced211e81f553aacdafbe5..90252b388ad21b4d7d0e883172f8e5511797cee4 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Issue 16115 Repro with on-abnormal
 
index 6015ad80807649e5f59dddc01231ec85ddb8fd18..7c65691029d90e757b4febe839d361ecf341ade8 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Issue 16115 Repro with on-failure
 
index 903dc9ab92c22ba2eee130a7b7c6515d63912795..c241262c277967cfaa235e326978bce56d804e2a 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=TEST-51-ISSUE-16115
 
index 06bc1602f874bfe69e487dea615f810fc460f976..fbe9693f3a5ec660ca69dda0c949750999de3062 100755 (executable)
@@ -1,4 +1,5 @@
 #!/usr/bin/env bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
 set -eux
 set -o pipefail
 
index bab540773a5a24cacff42c9371e35fee51ea8988..b9f290975a8eab21bd91c1bfbcda79a6b43e7819 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Testsuite service
 
index ea133dbaadf6a0fefb677882e1bea92b0225744a..8a76ff6ed6db273aa55d5506fbd8b12e808f0e19 100755 (executable)
@@ -1,4 +1,5 @@
-#!/bin/bash
+#!/usr/bin/env bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
 set -ex
 set -o pipefail
 
index d4dd8cc72f8bb16ce872977bdeac0743b8cb815b..cf3adbbe61a11760e556f3f692c85b87dd94ae41 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=TEST-53-ISSUE-16347
 
index 3eef94bc148fab082f0b62cd21bccad9752397c9..84cd66129d007e40c166bf8b772e26161a5a7b14 100755 (executable)
@@ -1,4 +1,5 @@
 #!/usr/bin/env bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
 set -eux
 set -o pipefail
 
index 862dd1c0fbf9e886171e898577097c87392ca7a7..ba8cdad5cb1043380e5ed901803a5ac2a9f24ae2 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=TESTSUITE-54-CREDS
 
index eb7259796125874301e3202da9729ea7007c50d9..6fc32b0a5b5574551bf498d08b2a21143dd413fb 100755 (executable)
@@ -1,4 +1,5 @@
 #!/usr/bin/env bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
 # shellcheck disable=SC2016
 set -eux
 
index d1595ad150297a18b8d9d51e6209a7804f7a5686..df1ea483fb23732155b3ec6b6d81265f986065dd 100755 (executable)
@@ -1,4 +1,5 @@
 #!/usr/bin/env bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
 # Don't use set -x here, since it generates a lot of output and slows
 # the script down, causing unexpected test fails.
 set -eu
index 7aa794b9f9a241bce19c2c5b5b299e13becba8a8..675273ab47e3b4c2503e6bd00e1d3381079c40f0 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Create a lot of memory pressure
 
index aca6bc4ab97690d4376ee6ef0c5b8e2b03d39213..49028e8ddc37416808d24e17cefd44cb75945ec9 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=No memory pressure
 
index 457e4a587ab33a29554c0787a5fb42ba80ffcd04..3b649314549f91db794d2a5b839f5cd5749f8159 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Create some memory pressure
 
index a1accbc22f4021fdeda636be3be57f7fdb38a9fd..d117b754baa6ad7bb454c55028b0e4485f9d4a17 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Test slice for memory pressure kills
 
index 65cc1e6815595ede582a99b2e696bdc701bceb8c..00fb49919f410929d43f2a98c8b5516347ec6ac0 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=TESTSUITE-55-OOMD
 After=user@4711.service
index 945e192420af6a6388e119fdd945fc225a734cee..b265c8cce76449a8c6e7022a6a0c1b7dd41a80de 100755 (executable)
@@ -1,4 +1,5 @@
 #!/usr/bin/env bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
 set -eux
 set -o pipefail
 
index e4b6ee3c299d114417b0bf8bb5dd5a9c0cbd849f..f8115a2ecd480a81826db84de04c179ac6685230 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Unit with BindsTo=
 BindsTo=testsuite-57-bound-by.service
index df66a8fe84c42f5aa0ec2e6a474e61c13104c545..a2df5a1954b87a697a1700324e1b0f0158ceba1a 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Unit with BoundBy=
 
index 07d8ddde9d030fe00aabbe72e3f98a78b4b7faa8..54d2330742e1f71448c8e224cd5f19a4081a35dc 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Failing unit
 OnFailure=testsuite-57-uphold.service
index cdca7d445170f1ee82b545a6902c8faa6d9d1288..1a25d9e3717b1260183880a4afc7f40d1ad8b258 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Stop Propagation Receiver
 Wants=testsuite-57-prop-stop-two.service
index a462faf353151d25047c1fcd5b1ccd8a4613bbfb..2bcd209e167243ab37005832be7fbad6391297b4 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Stop Propagation Sender
 
index 7fa268247f9b099bd603ec8481be0ea66e4003ef..cd8b51477f2de6f979aa74f20206e896edf76f53 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Shortlived Unit
 StopWhenUnneeded=yes
index 8c48d3a2d57f1d67e203ea49ff3ac31e982c2e0f..164fb0f1de1ccfe261407f666502b5e1082b3c67 100755 (executable)
@@ -1,5 +1,5 @@
 #!/usr/bin/env bash
-
+# SPDX-License-Identifier: LGPL-2.1-or-later
 set -ex
 
 if [ -f /tmp/testsuite-57.counter ] ; then
index ac1071fbba5c4ac423f7fbfb0380f5d0752e8efd..ae1f46f30cad98e2a9309839cdbc8444dbf6ea6d 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Succeeding unit
 OnSuccess=testsuite-57-fail.service
index d2b3828375ca38a687e4eeab632d2a58438851ae..eba97f509d06aa6065a0d04ef6eb7b390f01109f 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Upholding Unit
 Upholds=testsuite-57-short-lived.service
index cab23afb442dc52ba61b76efa498f6837391a14d..d3ec955d4d37eb8e5be9b191e7f9fa6fc595eb42 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=TEST-57-ONSUCCESS-UPHOLD
 
index 5db82b8437afec0ddaab019d4a3ff7e2f6cadaa9..66d946bebc5d0c9e831fd4b8e43afb4bbbca82ad 100755 (executable)
@@ -1,4 +1,5 @@
 #!/usr/bin/env bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
 
 set -eux
 set -o pipefail
index b962eb0f0fa2587f81d8a67f81ce2cffad618283..f843527acab094edd69b6fd3823d76543c9dd4eb 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=TEST-58-REPART
 
index ae177ac4286d728f9649b40cdbaf63100dbbfa57..16cd8385fb82aa3589aeaca53fce5358511a2331 100755 (executable)
@@ -1,4 +1,5 @@
 #!/usr/bin/env bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
 set -eux
 set -o pipefail
 
index 66d06866c89b8b2b5a21470356090cb44ec16490..f85cfab0847cea8f6c16f2e56f301a4c4db0b2dc 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=TEST-59-RELOADING-RESTART
 
index 459d6e64038f6a4d4ae9a93a2408bd99160f7216..143e44ec6373aebcd4ba079b8f66f16d967e63f9 100755 (executable)
@@ -1,4 +1,5 @@
 #!/usr/bin/env bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
 set -eux
 set -o pipefail
 
index 3715c4f341c82b2442c6904c1d8ce1ccb4171aab..18024d12d2151a0468cf4afb35fc488cc6310574 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=TEST-60-MOUNT-RATELIMIT
 
index 06526776fdbef21c96b5ed34a3370c86cab95c27..eb174f00ed481aec4931bfa9d907ffc369406812 100755 (executable)
@@ -1,4 +1,5 @@
 #!/usr/bin/env bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
 set -eux
 set -o pipefail
 
index 908ff7ef5d1c6108172f5565fdb4d777c1a48094..568960c21db12bb4eba933030001f11af3f1b81f 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=TEST-61-UNITTESTS-QEMU
 
index ef9b6b57c5fd372dd05275da80fcecb241cba6ce..748e24a7ca04e5351eccd58c8bebd3eb19688b0a 100755 (executable)
@@ -1,4 +1,5 @@
 #!/usr/bin/env bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
 set -eux
 set -o pipefail
 
index b8e15c992595791313cb374d49ed391da0974757..fa3a7e77b2f0ee65935ff2c5212ee15910944e9b 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=TEST-62-RESTRICT-IFACES-all-pings-work
 [Service]
index 51328b0bce7982f31a70c424a07b758a6e3d629f..b83362db89820dda8d31c93f12b1bfc8a21ce42b 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=TEST-62-RESTRICT-IFACES-allow-list
 [Service]
index 54ab1965ffda573ba8295474f9a88715c2297ec6..b6c8e7aa87f35789ffd50706d26383ea6e7f0f8a 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=TEST-62-RESTRICT-IFACES-deny-list
 [Service]
index 1d267a9cbe3a546b2a68d21de459ca7324ff4d28..94c7b534683a3b6471f3e8a18a3a1bbcd5ced278 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=TEST-62-RESTRICT-IFACES-empty-assigment
 [Service]
index b69485edac5abb1234f5b36d561261e8ada4ad5f..38664da4938bcdc2e7ae142d4d676e66220a0722 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=TEST-62-RESTRICT-IFACES-invert-assigment
 [Service]
index faaa2c85e3dad67618a130b5f89913b490ccb783..9cbd445e3c81e68cee03989e10d4f4849f8c8244 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 Description=TEST-62-RESTRICT-IFACES
 
 [Service]
index 140ccfe36f08ae1968e38939e3637f005bf95554..ee67c94ab1bd1ac33f077a17f50d66600130c79c 100755 (executable)
@@ -1,4 +1,5 @@
 #!/usr/bin/env bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
 set -ex
 set -o pipefail
 
index 04122723d450040c9098d65bcc0cad1b59df4c82..0a8d143be909a785fcb72a6878a36d7e53aee68c 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=TEST-63-ISSUE-17433
 
index 0f8cfa3770ce707e13ab946a9cfe9288cde0ac5f..10b61e7e532810a7b0cc36babadf8283ac02d0ad 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=TEST-64-UDEV
 
index 6f8382707facfc17d024abf069564bdd46fb1d60..10cd59f47226afd7dad3c91236ab6203a02199ef 100755 (executable)
@@ -1,4 +1,5 @@
 #!/usr/bin/env bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
 # vi: ts=4 sw=4 tw=0 et:
 
 set -eux
index 5b4a092f5934f0ce16d63806f234300eb3633710..3610bafde25e381cd904d138cdbaef74857cf7a0 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=TEST-65-ANALYZE
 
index 95b18e5e2359cfa416efb2fb59014488e65f3fee..3c3d795d63dce786ab5b368d566daae822705240 100755 (executable)
@@ -1,4 +1,5 @@
 #!/usr/bin/env bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
 # shellcheck disable=SC2016
 set -eux
 
diff --git a/test/units/testsuite-66-deviceisolation.service b/test/units/testsuite-66-deviceisolation.service
new file mode 100644 (file)
index 0000000..9da4a08
--- /dev/null
@@ -0,0 +1,10 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
+[Unit]
+Description=Service that uses device isolation
+
+[Service]
+DevicePolicy=strict
+DeviceAllow=/dev/null r
+StandardOutput=file:/tmp/testsuite66serviceresults
+ExecStartPre=rm -f /tmp/testsuite66serviceresults
+ExecStart=/bin/bash -c "while true; do sleep 0.01 && echo meow > /dev/null && echo thisshouldnotbehere; done"
diff --git a/test/units/testsuite-66.service b/test/units/testsuite-66.service
new file mode 100644 (file)
index 0000000..7e9dc3b
--- /dev/null
@@ -0,0 +1,8 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
+[Unit]
+Description=TESTSUITE-66-DEVICEISOLATION
+
+[Service]
+ExecStartPre=rm -f /failed /testok
+ExecStart=/usr/lib/systemd/tests/testdata/units/%N.sh
+Type=oneshot
diff --git a/test/units/testsuite-66.sh b/test/units/testsuite-66.sh
new file mode 100755 (executable)
index 0000000..fba42d1
--- /dev/null
@@ -0,0 +1,27 @@
+#!/usr/bin/env bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
+set -eux
+set -o pipefail
+
+RESULTS_FILE=/tmp/testsuite66serviceresults
+
+systemd-analyze log-level debug
+systemd-analyze log-target console
+
+systemctl start testsuite-66-deviceisolation.service
+
+sleep 5
+grep -q "Operation not permitted" "$RESULTS_FILE"
+
+systemctl daemon-reload
+systemctl daemon-reexec
+
+systemctl stop testsuite-66-deviceisolation.service
+
+grep -q "thisshouldnotbehere" "$RESULTS_FILE" && exit 42
+
+systemd-analyze log-level info
+
+echo OK >/testok
+
+exit 0
index 1a7e5b371a456089c2eb16ce0498618662b2d171..6bcbfec555b75af55bba76f9acb83017f74332fd 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=Testsuite target
 Requires=multi-user.target
index 916737d4153ef0b2ef2507bb5ae05908a7ac485c..1bc5e1c228640f925b57916c633f9ec7c35a2bc1 100644 (file)
@@ -1,2 +1,3 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=override0
index c6c2438f73ad129056ab54c92ae11eafa6f54692..17fe084f1336873172e57c0d06c4fb66bab86ec6 100644 (file)
@@ -1,2 +1,3 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Documentation=man:override1
index 62fafd2e3bc95556a5e2feece7b0c34634d9d21d..5b4878493571112da8dba02de5fcc302673e4100 100644 (file)
@@ -1,2 +1,3 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Documentation=man:override2
index b9616da8a84008f52d3957696b7a496e8a00650f..4d3423ad0ea45b281fc713b16e5782e6737780c7 100644 (file)
@@ -1,2 +1,3 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Documentation=man:override3
index b38b3604b80c9af2fa0a8bde1a52096d14e5fe2d..4aca9047a3d5a57e6740da4692d731898e641008 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=A unit with multiple dashes
 Documentation=man:test
index 982c3621a67de7c448db7a99b959895df126470a..e249b205e5bf10ff59db7e6b0056d03665de29e2 100644 (file)
@@ -1,2 +1,3 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Unit]
 Description=override4
index 56b72c98f75904b9a5d878a28522f25dd8e7fa6c..6eb7c19eab3d1397ad07c418854ca16b31063d1f 100644 (file)
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
 [Service]
 Type=oneshot
 RemainAfterExit=yes
diff --git a/units/integritysetup-pre.target b/units/integritysetup-pre.target
new file mode 100644 (file)
index 0000000..da2aca9
--- /dev/null
@@ -0,0 +1,14 @@
+#  SPDX-License-Identifier: LGPL-2.1-or-later
+#
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+[Unit]
+Description=Local Integrity Protected Volumes (Pre)
+Documentation=man:systemd.special(7)
+RefuseManualStart=yes
+Before=integritysetup.target
diff --git a/units/integritysetup.target b/units/integritysetup.target
new file mode 100644 (file)
index 0000000..371490f
--- /dev/null
@@ -0,0 +1,12 @@
+#  SPDX-License-Identifier: LGPL-2.1-or-later
+#
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+[Unit]
+Description=Local Integrity Protected Volumes
+Documentation=man:systemd.special(7)
index 93c3bf608abe3287878c7765acf0ad1ea0f7be08..c106284e0fd2b41d2ccb73a6f65369de8a0a27be 100644 (file)
@@ -13,6 +13,9 @@ units = [
         ['veritysetup-pre.target',              'HAVE_LIBCRYPTSETUP'],
         ['veritysetup.target',                  'HAVE_LIBCRYPTSETUP',
          'sysinit.target.wants/'],
+        ['integritysetup-pre.target',           'HAVE_LIBCRYPTSETUP'],
+        ['integritysetup.target',               'HAVE_LIBCRYPTSETUP',
+         'sysinit.target.wants/'],
         ['dev-hugepages.mount',                 '',
          'sysinit.target.wants/'],
         ['dev-mqueue.mount',                    '',
index bd9f71acefa926284e40a9d8dcb312c312dcc33e..bad28c3f051bd1e9f168444778e3f49a0a33becb 100644 (file)
@@ -8,7 +8,7 @@
 #  (at your option) any later version.
 
 [Unit]
-Description=Remote Verity Integrity Protected Volumes
+Description=Remote Verity Protected Volumes
 Documentation=man:systemd.special(7)
 After=remote-fs-pre.target veritysetup-pre.target
 DefaultDependencies=no
index ffa45ba049aebdfb84cf637a3fd64f3e64f67185..6acce036dfda9f586e2526562883da18463bd844 100644 (file)
@@ -38,7 +38,7 @@ ProtectSystem=strict
 Restart=on-failure
 RestartKillSignal=SIGUSR2
 RestartSec=0
-RestrictAddressFamilies=AF_UNIX AF_NETLINK AF_INET AF_INET6 AF_PACKET AF_ALG
+RestrictAddressFamilies=AF_UNIX AF_NETLINK AF_INET AF_INET6 AF_PACKET
 RestrictNamespaces=yes
 RestrictRealtime=yes
 RestrictSUIDSGID=yes
index be065f335fba5c58aab1f0ad24832da097d21363..869575a9839c34542deaf266ac0feffdade4ed60 100644 (file)
@@ -8,7 +8,7 @@
 #  (at your option) any later version.
 
 [Unit]
-Description=Local Verity Integrity Protected Volumes (Pre)
+Description=Local Verity Protected Volumes (Pre)
 Documentation=man:systemd.special(7)
 RefuseManualStart=yes
 Before=veritysetup.target
index 0ac3ad3bd061a71008356aa093bea299339cca5e..c75b15375e2096206a68e4359d2f5afd100d3c61 100644 (file)
@@ -8,5 +8,5 @@
 #  (at your option) any later version.
 
 [Unit]
-Description=Local Verity Integrity Protected Volumes
+Description=Local Verity Protected Volumes
 Documentation=man:systemd.special(7)